如果两个不同的依赖数组同时更新,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。