Обновление поля вложенного объекта без повторной визуализации представлений в React Redux - PullRequest
0 голосов
/ 30 декабря 2018

Я занимаюсь разработкой веб-приложения с использованием React и Redux в качестве интерфейсной среды JavaScript.У меня возникла небольшая проблема с отображением представления и обновлением значения состояния / хранилища Redux.

У меня есть поле ввода, которое обновляет значение состояния Redux.Это обработчик события для onChange моего текстового поля.

_handleNameInput= (event) => {
     this.props.updateField({
             name: 'name',
             value: event.target.value,
     })
}

В редукторе я обновляю поле состояния следующим образом:

case RESTAURANT_CATEGORY_UPDATE_FIELD: {
            let freshState = { ...state };
            _.set(freshState, action.payload.name, action.payload.value);
            return freshState;
        }

Я использую Lodash для обновленияполе объекта состояния.

Это мое состояние по умолчанию

let defaultState = {
     name: ''
}

Когда пользователь вводит данные, я отображаю значение текущего состояния в представлении, как это.

<h1>Name is: {this.props.name}</h1>

Приведенный выше сценарий работает совершенно нормально.Он отображает живые изменения, в то время как я также изменяю значение ввода.Проблема началась, когда я использую вложенный объект в состоянии.Я обновил defaultState до этого.

let defaultState = {
     form: {
        name: '',
     }
}

Затем в обратном вызове я обновляю вот так.

this.props.updateField({
      name: 'form.name',
      value: event.target.value,
})

Это обновление значений состояния / хранилища избыточного значения вложенного свойстваобъект.Проблема в том, что когда я отображаю живые изменения, как это

<h1>{this.props.form.name}</h1>

Это не обновляет / не отображает представление.Как я могу это исправить?

1 Ответ

0 голосов
/ 30 декабря 2018

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

В первом случае name является реквизитом верхнего уровня иэто изменение обнаружено, поэтому обновление выполняется.

Во втором случае form - это реквизит верхнего уровня, который не изменился, поэтому обновление предотвращено.

Как предлагается в комментарияхВы можете использовать immer, чтобы гарантировать, что объект form будет заменен новым объектом с обновленным свойством name.

import produce from "immer";

return produce(state, draft => {
  _.set(draft, action.payload.name, action.payload.value);
});

Во втором случае он будет эффективно выполнять следующее:

return {
  ...state,
  form: {
    ...state.form,
    name: action.payload.value
  }
};

Однако я хотел бы предложить вам пересмотреть действие и редуктор, которые произвольно обновляют глубоко вложенные поля и вместо этого используют что-то более конкретное.

RESTAURANT_CATEGORY_UPDATE_FORM_FIELD

return {
  ...state,
  form: {
    ...state.form,
    [action.payload.name]: action.payload.value
  }
};

или

return produce(state, draft => {
  draft.form[action.payload.name] = action.payload.value;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...