Я использую redux для перемещения поискового фильтра через приложение к компонентам.
У меня есть компонент, в котором я настраиваю фильтры и вызываю функцию диспетчеризации, используя
this.props.dispatch(setFilter(newFilter));
Я использую ползунки / компоненты диапазона для установки значений, эти компоненты имеют метод handleAfterChange, который настроен для вызова упомянутой функции диспетчеризации. Это нормально работает.
У меня также есть фильтры, которые настраиваются нажатием кнопок, я создал обработчик onClick, и этот вызов обработчика упомянул функцию. Я проверил, что я отправляю в параметр setFilter functions (newFilter), и это то, что я хочу настроить.
Мое установленное действие определено:
export const setFilter = (filter = {}) => {
return {
type: SET_FILTER,
filter
};
};
Мой редуктор:
const searchFilter = (prevState = INITIAL_STATE.filter, action) => {
switch (action.type) {
case SET_FILTER: {
// prevState is already the state
// I want to set up in this reducer
console.info(prevState);
return Object.assign({}, prevState, action.filter);
}
case RESET_FILTER: {
return INITIAL_STATE.filter;
}
default: {
return prevState;
}
}
};
Проблема в том, что prevState уже является объектом, который я хочу настроить в reducer. Я проверяю (в другом компоненте), был ли изменен фильтр, и из-за этого я получаю одинаковые значения prevProps и nextProps, поэтому никаких действий запускаться не будет.
Итак, каким-то образом отправленные изменения уже находятся в редукторе как prevProps.
Я использую инструмент ведения журнала redux, где я могу видеть информацию о транзакции redux - предыдущее состояние, действие и следующее состояние. Я не знаю, почему предыдущее состояние уже является состоянием, которое необходимо настроить. Я также установил Redux devTools в Chrome, как вы предложили, и я вижу, что было запущено только одно действие, а diff из prevState и nextState - это то, что я ожидаю изменить.





В редукторе searchFilter вы возвращаете prevState таким, какой он есть, без изменения.
return prevState //which is reference to prevState = INITIAL_STATE.filter
правильный путь (не уверен в государственном устройстве),
default: {
return {...prevState};
}
ИЛИ ЖЕ
return Object.assign({}, prevState);
Да, но это в том случае, если тип действия не SET_FILTER или RESET_FILTER, что не так, потому что он переходит в случай, когда action.type равен SET_FILTER
Первоначально ваш случай по умолчанию выполняется. Итак, ссылка обновляется без редукторов. Используйте вышеуказанный метод также для RESET_FILTER. Он будет работать.
Это неверно, если вам не нужно изменять состояние, верните его без изменений. В противном случае вы заставите React выполнять ненужную согласование рендеринга.
@DominicTobias согласен, но часть хитрости - это ссылка на обновление без действия-дезактивации
@RIYAJKHAN, ты был частично прав. Каким-то образом я напрямую изменял хранилище redux, даже если я делал все изменения объекта через Object.assign (...). В конце концов, мне пришлось создать копию изменяемого объекта - JSON.parse (JSON.stringify (фильтр)), а затем обновить этот новый объект и отправить его в хранилище redux.
@RIYAJKHAN был частично прав.
Каким-то образом я изменял хранилище redux напрямую, даже если я делал все изменения объекта через Object.assign(...).
В конце концов, мне пришлось создать копию объекта, который я изменял - JSON.parse(JSON.stringify(filter)), а затем обновить этот новый объект и отправить его в хранилище redux.
Не уверен, что вы имеете в виду, большинство людей называют prevState просто состоянием, поскольку это текущее состояние для этого редуктора. Если он уже обновлен, то вы обновили его, почему бы вам не взглянуть на вкладку Redux (установить, если у вас ее нет) в Chrome devtools и не посмотреть, что его обновляет?