Итак, у меня есть два разных массива useEffect и зависимостей.
const [dateFilterSort, setDateFilterSort] = useState({
queryText: initialQueryText(params.sortName),
cardText: initialCardText(params.sortName),
start: params.startDate
? moment(params.startDate).startOf('day').toDate()
: undefined,
end: params.endDate
? moment(params.endDate).endOf('day').toDate()
: undefined,
});
useEffect(() => {
if (params.endDate) {
setDateFilterSort({
...dateFilterSort,
end: moment(params.endDate).endOf('day').toDate(),
});
}
}, [params.endDate]);
useEffect(() => {
if (params.startDate) {
setDateFilterSort({
...dateFilterSort,
start: moment(params.startDate).startOf('day').toDate(),
});
}
}, [params.startDate]);
Проблема здесь в том, что params.endDate и params.startDate обновляются одновременно. Таким образом, dateFilterSort.start обновляется правильно, но, поскольку dateFilterSort.end выше, dateFilterSort.end был перезаписан вторым useEffect.
Есть ли способ решить эту проблему?
Я подумал, что могу поставить два useEffect, как показано ниже.
useEffect(() => {
if (params.startDate) {
setDateFilterSort({
...dateFilterSort,
start: moment(params.startDate).startOf('day').toDate(),
});
}
if (params.endDate) {
setDateFilterSort({
...dateFilterSort,
end: moment(params.endDate).endOf('day').toDate(),
});
}
}, [params.startDate, params.endDate]);
что вызвало бесконечный цикл...
Кроме того, просто чтобы посмотреть, смогу ли я обновить params.end, я использую setTimeout, но снова вызываю бесконечный цикл....
useEffect(() => {
if (params.endDate) {
setTimeout(() => {
setDateFilterSort({
...dateFilterSort,
end: moment(params.endDate).endOf('day').toDate(),
});
}, 500);
}
}, [params.endDate]);
useEffect(() => {
if (params.startDate) {
setDateFilterSort({
...dateFilterSort,
start: moment(params.startDate).startOf('day').toDate(),
});
}
}, [params.startDate]);
@sebasaenz params — это состояние. Я добавил, как выглядит состояние Спасибо.
вы не должны копировать состояние или производное состояние



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Недавно у меня была похожая проблема. В моем случае второй сеттер перезаписывал первый.
Хорошее решение, которое я придумал, заключалось в том, чтобы сначала сделать необходимые изменения локально, а затем только один раз установить состояние:
useEffect(() => {
// Choose your favorite copy technique,
// I'll go with spread operator for simplicity
const dateFilterSortCopy = { ...dateFilterSort }
if (params.startDate) {
dateFilterSortCopy.startDate = moment(params.startDate).startOf('day').toDate()
}
if (params.endDate) {
dateFilterSortCopy.endDate = moment(params.startDate).startOf('day').toDate()
}
setDateFilterSort(dateFilterSortCopy);
}, [params.startDate, params.endDate]);
Это также избавляет от ненужных повторных рендеров.
Большое спасибо! это решило мою проблему! У меня есть быстрый вопрос относительно вашего кода. последняя часть setDateFilterSort({...dateFilterSortCopy}); этого не может быть setDateFilterSort({dateFilterSortCopy}); ? нам нужен оператор спреда?
На самом деле должно быть setDateFilterSort(dateFilterSortCopy). Только что отредактировал, хороший улов!
Я пробовал без оператора распространения и не работал. Так что в некоторых случаях может понадобиться его использовать. Но все равно большое спасибо!
Является ли
paramsпеременной состояния или реквизитом?