Является ли плохой практикой сохранять сильное состояние, связанное с пользовательским интерфейсом, внутри компонента реакции? - PullRequest
3 голосов
/ 09 апреля 2019

Я перевожу мое приложение activJs на redux / mobx.На данный момент у меня есть 3 компонента, каждый из которых имеет в своем состоянии следующую структуру:

name:string,
surname:string,
showError: boolean,
loading:boolean

Как видите, имеет смысл переместить имя / фамилию в централизованное хранилище, чтобы поддерживатьглобальное состояние.Я не очень уверен насчет showError и загрузки: они являются логическими значениями, предназначенными для отображения сообщения об ошибке и счетчика внутри конкретного компонента.

Лично мне не нравится идея помещать такие "UI-связанныесостояние "в централизованном состоянии, я бы хотел, чтобы он оставался внутри конкретного компонента, так как другим компонентам никогда не потребуется доступ / обновление таких вещей.

Так что моя идея заключается в следующем:

this.state = {showError, loading};
this.businessState = props.state;

Короче говоря, я продолжу обновлять «состояние» с помощью функции React setState (), оставляя для редукции / моба управление так называемым «бизнес-состоянием».

Может ли этобыть хорошей практикой или я делаю что-то особенно плохое?

Ответы [ 3 ]

1 голос
/ 09 апреля 2019

Лично я бы предложил сделать store для большинства components, и из моего опыта большинство stores на самом деле ViewStore's. Если у вас есть похожая логика, такая как loading и errors для нескольких components, тогда еще проще сделать что-то вроде этого:

class BaseViewStore {
    @observable loading = false
    @observable showError = false
}

Тогда ваш component store просто расширит это store, и у вас будет логика многократного использования в этом base store. Все, что специфично для component, конечно же, войдет в этот специфический store. Таким образом, ваш components будет чистым, не будет иметь personal state (внутри самого component) и может быть легко заменен другими компонентами, поскольку ваше поведение (состояние) будет в stores.

1 голос
/ 09 апреля 2019

У меня лично нет проблем с этим, так как 'loading' и 'showError' относятся к состоянию, а не к компоненту пользовательского интерфейса. Это в основном говорит, когда я заполняю свое состояние из вызова API, это уже сделано и что-то пошло не так? Компонент пользовательского интерфейса отображается соответственно.

Я бы сделал showError строкой или строкой [] в зависимости от структуры ошибок, генерируемых вашей системой BE.

Я бы также разбил ваше состояние на конкретные редукторы, которые выполняют определенные бизнес-функции и состояния загрузки на основе определенных бизнес-функций, а не нагрузки на компонент на странице.

Надеюсь, это поможет.

0 голосов
/ 09 апреля 2019

Я не уверен, что это лучшая практика или нет. Но состояние загрузки используется, когда вы выполняете какое-то асинхронное действие, такое как получение данных из API. Лучшей практикой для получения таких данных является действие. И что я обычно делаю внутри действия, так это отправляю состояние загрузки перед вызовом API и отправляю редуктор, который устанавливает загрузку в false после получения данных.

Итак, на мой взгляд. Я бы сохранил состояние загрузки внутри Redux вместо использования компонента компонента.

Было бы что-то вроде этого

action.js

getData = () => {
   return (dispatch) => {
      dispatch({ type: LOADING });
      callApiToGetData()
         .then(data => {
            dispatch({ type: SUCCESS, data })
         })
         .catch(e => {
            dispatch({ type: ERROR, error: e })
         })
   }
}

reducer.js

const initialState = {
  data: null,
  loading: false,
  error: null
}

function reducer(state = initialState, action) {
  switch (action.type) {
    case LOADING:
       return { ...state, loading: true }
    case SUCCESS:
       return { ...state, loading: false, data: action.data, error: null }  
    case FAIL:
       return { ...state, loading: false, error: action.error }
    default:  
       return state
}
...