如果两个不同的依赖数组同时更新,react useEffect 如何更新数据
react useEffect how to update data if two different dependency arrays updates at the same time
所以我有两个不同的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]);
我最近遇到了类似的问题。在我的例子中,第二个 setter 覆盖了第一个。
我想到的一个好的解决方案是先在本地进行必要的更改,然后只设置一次状态:
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]);
这也节省了不必要的 re-renders。
所以我有两个不同的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]);
我最近遇到了类似的问题。在我的例子中,第二个 setter 覆盖了第一个。
我想到的一个好的解决方案是先在本地进行必要的更改,然后只设置一次状态:
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]);
这也节省了不必要的 re-renders。