猿问

useEffect 内的 setTimeout 和 useState

我的 useState 挂钩中有一个对象数组,我想更改每个数组元素的一个属性,假设它看起来像:


const array = [{id:1, isDisplayed: false}, {id:2, isDisplayed: false}, {id:3, isDisplayed: true}]

虽然我尝试使用setTimeout内部useEffect钩子来更改displayed不需要的任何地方的true属性isDisplayed: true,但它会等待专用时间,并立即更改所有内容,但我想要实现的是用自己的延迟更改每个元素。我的意思是像 const DELAY = 2000setTimeout 之类的东西setTimeout(() => ... , DELAY * id) ,因为当我渲染 jsx 时,所有内容都会同时出现,我只想在每个元素出现之间产生小的延迟。例如,第一个元素在 2 秒后出现,第二个元素在 3 秒后出现(不是第一个元素后 3 秒)


我当前的代码如下所示:


React.useEffect(() => {

 setTimeout(() => {

  setArray(array.map((item)=> !item.isDisplayed ? {...item, displayed: true} : item))

 }, DELAY * Math.floor(Math.random() * 5);

}, [])


杨魅力
浏览 192回答 2
2回答

慕勒3428872

如果某些项目不可见,您可以设置超时并触发更新。并跟踪是否显示新项目revealed,如果没有显示新项目,则停止流程。function TodoApp() {&nbsp; const [items, setItems] = React.useState([&nbsp; &nbsp; { id: 1, isDisplayed: false },&nbsp; &nbsp; { id: 2, isDisplayed: false },&nbsp; &nbsp; { id: 3, isDisplayed: false },&nbsp; ]);&nbsp; React.useEffect(() => {&nbsp; &nbsp; let currentTimeout = null;&nbsp; &nbsp; const displayMoreItems = () => {&nbsp; &nbsp; &nbsp; setItems(prevItems => {&nbsp; &nbsp; &nbsp; &nbsp; let revealed = false;&nbsp; &nbsp; &nbsp; &nbsp; const nextItems = prevItems.map(item => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!revealed && !item.isDisplayed) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; revealed = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return { ...item, isDisplayed: true };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return item;&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; if (revealed) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentTimeout = setTimeout(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; displayMoreItems();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, 1000);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return nextItems;&nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; };&nbsp; &nbsp; currentTimeout = setTimeout(() => {&nbsp; &nbsp; &nbsp; displayMoreItems();&nbsp; &nbsp; }, 1000);&nbsp; &nbsp; return () => {&nbsp; &nbsp; &nbsp; if (currentTimeout) {&nbsp; &nbsp; &nbsp; &nbsp; clearTimeout(currentTimeout);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; };&nbsp; }, [setItems]);&nbsp; return <div>{items.map(item => (item.isDisplayed ? item.id : null))}</div>;}ReactDOM.render(<TodoApp />, document.querySelector('#app'));这是一个小提琴

侃侃无极

const DELAY = 2000;React.useEffect(() => {&nbsp;let count = 1;&nbsp;array.forEach((item) => {&nbsp; &nbsp;if (!item.displayed) {&nbsp; &nbsp; &nbsp;setTimeout(() => {&nbsp; &nbsp; &nbsp; &nbsp; item.displayed = true;&nbsp; &nbsp; &nbsp; &nbsp; setArray([...array]);&nbsp; &nbsp; &nbsp;}, DELAY * count);&nbsp; &nbsp; &nbsp;count ++;&nbsp; &nbsp;}&nbsp;})}, [])
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答