Таким образом, мой компонент настроен как контейнер, который может иметь x дочерних элементов, пользователь не может продвигаться вперед, пока каждый из дочерних компонентов не будет «готов» на основе различных условий. Я столкнулся с проблемой, когда некоторые из них настроены на готовность при первоначальном рендеринге без каких-либо условий. Если 2 из них находятся в одном контейнере, каждый из них захватывает один и тот же массив, скажем [false, false], а затем один устанавливает [true, false], а другой [false, true], а затем устанавливается [false, true] в состоянии. Я предполагаю, что это результат асинхронной установки состояния, поэтому он получает старое значение состояния в обоих вызовах. Как я могу это исправить?
const [readyArray, setReadyArray] = useState(
new Array(children.length).fill(false)
);
const setReady = (val, idx) => {
let newArray = Array.from(readyArray);
newArray[idx] = val;
if (isArrayTrue(newArray)) {
props.setReady(true);
}
setReadyArray(newArray);
};
Редактировать: функция также проверяет, является ли весь массив истинным, и вызывает другую функцию, чтобы сообщить HOC, что каждый дочерний элемент готов.
Используйте setReadyArray
обратный вызов вместо использования readyArray
в замыкании — таким образом, немедленные обновления состояния не будут перезаписывать друг друга:
const setReady = (val, idx) => {
setReadyArray(readyArray => readyArray.map(
(orig, i) => i === idx ? orig : val
));
};
я не думаю, что может помочь.
Есть еще одна сложность, я также проверяю в этой функции, полностью ли массив верен, и если это так, то вызываю другую функцию, которая передается в реквизитах. Я изменил ваш код на этот setReadyArray((readyArray) => { let newArray = readyArray.map((orig, i) => (i === idx ? orig : val)); if (isArrayTrue(newArray)) { props.setReady(true); } return newArray; });
, но он все равно не работает
@user3645925 user3645925 эта проверка должна происходить в отдельном useEffect
.
По какой-то причине это не работает в случае, когда есть только один элемент? Однако в случае одновременного вызова двух элементов это работает отлично.
Исправлено, нужно было !== вместо === они поменяли местами троичный оператор true/false
Я предполагаю, что проблемы связаны с
react component life cycle problem
, а не сstate racing condition
, даже если вы правы, состояние реакции - это асинхронная настройка. \n проблема заключается в том, что состояние компонента будет зависеть от длины дочерних элементов, что создает проблему жизненного цикла. Исправление состоит в том, чтобы не использовать children.length, вместо этого использовать большое число, которое всегда больше, чем длина ваших детей.