React useEffect 在排序条目后不会重新渲染

时间:2021-05-27 11:48:43

标签: javascript reactjs

我有一个条目列表,我希望始终根据日期对其进行排序。所以我在 useEffect 钩子中加入了一个排序方法,它应该在添加新条目后运行。

  useEffect(() => {
    setEntries(entries.sort((a, b) => {
      if (a.date > b.date) {
        return -1;
      }
      else if (a.date < b.date) {
        return -1
      }
      else {
        return 0;
      }
    }));
 }, [entries])

由于 entries 在依赖数组中,useEFfect 应在条目更改(添加条目)后触发。当 useEffect 运行时,setEntries 被调用,因此状态发生了变化,我认为它应该重新渲染。不幸的是,这并没有发生。

这里出了什么问题?

更新列表的代码:

function addEntry(date, description, header, amount) {
    if (!date || !description || !header || amount < 0) {
      return;
    }
    setEntries(prev => ([
      {id: Date.now(), date: date, description: description, header: header, amount: amount}, ...prev
    ]))

    setDescription('');
    setHeader('');
    setAmount('');
   }

一开始我尝试在此处合并排序功能,但是尽管此功能可以工作,但很奇怪我在更新后无法在同一函数中访问更新的 entries

3 个答案:

答案 0 :(得分:2)

useEffect 不连续运行 - 它在组件渲染后运行。除了无限循环,首先列表会呈现未排序,然后以排序的顺序再次重新呈现 - 看起来不像你想要的东西?

您可能正在寻找的是 useMemo

<块引用>

useMemo 只会在依赖项之一发生变化时重新计算记忆值。这种优化有助于避免每次渲染时进行昂贵的计算。

const sortedEntries = useMemo(() => {
    return [...entries].sort((a, b) => {
        if (a.date > b.date) {
            return -1;
        }
        else if (a.date < b.date) {
            return -1
        }
        else {
            return 0;
        }
    });
}, [entries])

答案 1 :(得分:0)

你改变你的状态,在这里也使用回调函数:

setEntries((prevEntries) => [...prevEntries].sort(...))

看起来 useEffect 启动了无限循环。您的依赖项是实体,您尝试在内部对其进行修改。最好在负责添加新条目的函数中对实体进行排序

在你的情况下,只需删除 useEffect 并在 addEntry 函数中移动排序逻辑

function addEntry(date, description, header, amount) {
    // ...other code
   setEntries(prev => ([
      {id: Date.now(), date, description, header, amount}, 
       ...prev
       ].sort(...your code...)))

     .... other code
  }

答案 2 :(得分:0)

所以就像我在评论中强调的那样,您不应该无条件地更新 useEffect 中的状态,其中该状态是一个依赖项。像这样的事情应该可以为您完成工作:

// after state declarations
const sortedEntries = useMemo(() => entries.sort(...), [entries]);

您的处理程序应更新 entries 而不是 sortedEntries。每当您更新条目时,都会计算一个新的 sortedEntries。由于它是记忆的,当其他一些不相关的状态更新时,它不会重新计算。