Состояние реакции не всегда может быть неизменным

Сегодня я решал проблему с компонентом, связанным с API контекста реакции, который удерживал состояние, которым я делился между двумя компонентами. Проверяя свои знания о хуках, я решил useReducer и обернуть контекстный API в хук. Вот статья, которую я использовал для начала.

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

Ну, я мало что понимал, но я настроил себя на неудачу еще до того, как что-то началось.

Суть всей моей жизни по управлению реакциями и состояниями: объекты, вложенные в другие объекты.

В этой статье я не собираюсь описывать, как настроить хук React Reducer с контекстным API. Я позволю это сделать другим гораздо более умным людям. Я просто опишу проблему и один из способов ее решения.

Проблема

Во многих местах реакции вы можете убить себя, передав объекты объектов своим функциям.

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

Это может быть особенно проблематично, когда вы работаете с состоянием в реакции.

Здесь у меня есть пример объекта начального состояния, который будет использоваться в редюсере.

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

state.attributes.name = 'blahdy'

может в конечном итоге изменить ваш initialState, даже если вы не отправили его обратно через редюсер.

Таким образом, даже если вы пытаетесь сделать это в своем редукторе, вы можете изменить свой initialState.

Решение

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

JSON.parse(JSON.stringify(initialState))

Если вы используете API контекста реакции. Обратите особое внимание на следующие места:

const myStateContext = React.createContext(initialState)

и тут

const [state, dispatch] = useReducer(myReducer, initialState)

Еще одна вещь, которую нужно сделать, это убедиться, что вы никогда не изменяете состояние напрямую. Так что избегайте чего-то вроде state.blah = 'blah' . Используйте оператор распространения или сделайте глубокую копию объекта, прежде чем назначать его чему-либо.

Вывод

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

Удачного кодирования!