Как вы должны обеспечить порядок обновления состояния в react?

#javascript #reactjs #state #settimeout #event-loop

Вопрос:

У меня есть пара заданных состояний для поставщиков, которые вызывают множество эффектов во всем моем приложении react. Они случаются спина к спине на крючке. Второе состояние набора имеет некоторые эффекты, которые оно запускает, и необходимо убедиться, что первый крючок полностью распространяется через приложение. В настоящее время первый из них не внес всех необходимых изменений, поэтому некоторые функции, запускаемые вторым, вызывают странное поведение. Как вы гарантируете, что второе произойдет только после того, как первое будет полностью распространено?

 setSomeStateValue(x);
setValueToTriggersEffectsThatRelyOnUpdatesFromTheOther(y);
 

Вот некоторые вещи, которые я проделал в этой работе, но у них есть свои проблемы:

1.) settimeout(…,0)

 setSomeStateValue(x);
setTimeout(otherSetState,0);
 

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

2.) следите за тем, что мне нужно установить, прежде чем вызывать состояние второго набора

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

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

Комментарии:

1. Я видел большие и сложные состояния в больших приложениях react, но никогда не сталкивался с этой проблемой. Похоже, что это, вероятно, связано с плохим дизайном вашего состояния и последующими эффектами, которые вызывают изменения состояния. Может ли это быть одно значение состояния (объект с несколькими полями) вместо этого? Так как же они связаны? Каков пример эффектов, которые являются проблематичными? Если вы не готовы к рефакторингу этого материала, то setTimeout , вероятно, это ваш лучший выбор, но это взлом и определенно создает плохой прецедент в вашей кодовой базе.

Ответ №1:

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

  1. используйте второй аргумент setState. Здесь обратный вызов вызывается только после обновления состояния setState. Следовательно, вы можете получить желаемое синхронное поведение.
 setState(updater, [callback])
 
  1. Используйте метод жизненного цикла componentDidUpdate ( для крючков это будет просто еще один эффект использования ). Если вы не хотите иметь сложные состояния в своем компоненте, просто создайте эффект с зависимостью от необходимого состояния и выполняйте свои операции там
 React.useEffect(() => {
 if( desired_state){
    secondSetState()
 },
 [ desired_state ]
}