Изменена ссылка на состояние избыточности при ручном обновлении состояния избыточности.

У меня есть проект React/Redux, в котором я использую Web Worker для расчета следующего состояния при отправке действия, а затем передаю новое состояние непосредственно в хранилище. , нравится:

let nextReducer = reducer => {
    return (state, action) => {
        if (action.type === 'WEBWORKER') {
            return action.payload;
        } else {
            return reducer(state, action);
        }
    };
};

let store = createStore(nextReducer(rootReducer));

Проблема в том, что когда я вручную передаю новое состояние в хранилище избыточности, у состояния теперь есть новая ссылка, и библиотека reselect не может правильно запомнить состояние. В результате представление всегда перерисовывается при каждом изменении состояния.

Дело в том, что я всегда думал, что у состояния всегда есть другая ссылка (даже без ручной установки), потому что правило состоит в том, что мы никогда не должны мутировать исходный объект состояния, но мы должны всегда возвращать новый. Итак, почему, если я использую свой rootReducer как есть, reselect работает нормально, а при настройке вручную - нет?


person Zosimas    schedule 16.07.2018    source источник
comment
Оценивает ли веб-воркер все состояние приложения или только его конкретную ветвь?   -  person Andrea Carraro    schedule 17.07.2018
comment
Веб-воркер просто запускает ту же функцию редуктора, которая запускается при условии else, с аргументами состояния и действия, которые передаются веб-воркеру в виде данных. Затем он отправляет результат обратно как действие с типом WEBWORKER и новым состоянием в качестве полезной нагрузки.   -  person Zosimas    schedule 17.07.2018


Ответы (1)


Связанные компоненты react-redux и reselect полагаются на равенство ссылок на объекты, чтобы предотвратить ненужные рендеринг/перерасчеты.

При отправке объектов веб-воркерам объект сериализуется, а затем десериализуется, таким образом, вы получите клон объекта, лишенный какого-либо равенства ссылок с исходным объектом.

Быстрое решение может заключаться в использовании serviceWorker только для оценки конкретной ветки состояния (или значения), которую необходимо обновить.

Учтите также, что в особых случаях reselect можно настроить на выполнять собственные глубокие проверки на равенство, и то же самое верно для react-redux connect -mapdispatchtoprops-mergeprops-options" rel="nofollow noreferrer">mapStateToProps конфигурация.

Поскольку равенство ссылок играет важную роль в архитектуре redux, стоит отметить, что оператор идентификации JS (===) сравнивает arrays, functions и objects по ссылке, а сравнивает numbers и strings. (плюс undefined, null, boolean) по значению.

person Andrea Carraro    schedule 17.07.2018
comment
Я это понимаю, но внутри редуктора я использую библиотеку seamless-immutable, которая должна возвращать новые экземпляры состояния каждый раз, когда оно изменяется. Но у меня никогда не было проблем со ссылкой на состояние до добавления веб-воркеров. - person Zosimas; 17.07.2018
comment
Если объект внутри структуры seamless-immutable останется нетронутым, тот же объект (ссылочное равенство) будет возвращен при доступе к immutableStructure.nestedObject - person Andrea Carraro; 17.07.2018
comment
Хорошо, это имеет смысл. Итак, какое-либо решение о том, как предотвратить повторный рендеринг? (кроме проверок shouldComponentUpdate) - person Zosimas; 17.07.2018