反应状态,一段时间后删除数组中的项目

React state, remove item in array after a while

我遇到了一个问题,我有一个数组形式的 React 状态。

当使用 setState 将项目添加到数组时,我想在例如五秒后将其删除。

类似于:

const {messages, setMessages} = useState([])

useEffect(() => {
    const timer = setTimeout(() => {
        setMessages(arr => arr.splice(i, 1))
    }, 5000)

    return () => clearTimeout(timer)
})

其中 i 是要删除的项目的索引。

举个具体的例子:我每秒点击一个按钮,这会向数组中添加一个项目。 5 秒后,第一项被删除。 6 秒后,第二个项目被删除。 等...

感谢您的帮助。

Array.prototype.splice 就地改变数组,这意味着 messages 状态数组引用永远不会改变并且 React 退出重新渲染。

Array.prototype.splice

The splice() method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.

Bailing out of a state update

If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the Object.is comparison algorithm.)

您可以使用 Array.prototype.filter 将先前的 messages 数组浅复制到新的引用中,指定匹配索引处的元素除外。

useEffect(() => {
  const timer = setTimeout(() => {
    setMessages(arr => arr.filter((_, index) => index !== i)) // *
  }, 5000);

  return () => clearTimeout(timer);
}, []); // <-- don't forget dependency array!

* 假定 i 在范围

中定义

您可以将数组中的每个项目设置为一个带有 timeRemaining 属性 的对象,然后使用 setInterval 每秒减少时间,直到它最终达到 0,此时点你会删除该项目。

useEffect(()=>{
  const interval = setInterval(()=>{
    setMessages(prev=>prev.filter(i=>i.timeRemaining>0).map((item)=>{
      return {
        ...item, timeRemaining: item.timeRemaining - 1
      }
    }))
  },1000)
  return ()=> clearInterval(interval)
},[])