React Native useState冲突,数据存储到一个点

u5rb5r59  于 2023-08-07  发布在  React
关注(0)|答案(1)|浏览(108)

我有一个预订项目。用户选择日期并进行预订。此预订将保存到mongo。然后我从mongo获取数据并显示它,用户有30分钟的付款时间。如果用户不付款,保留将从mongo删除,它将提供给其他用户。
下面使用useState显示计时器

const [timeOut, setTimeOut] = React.useState(0)

字符串
这里有一行显示数据

<th>{item.status === 'unPaid' ? `${formatTime(item.createdAt)}` : ''} </th>


then这里的formatTime函数

const formatTime = (time) => {

       setInterval(() => {
          // 1800000 = 30 min
          const timer = new Date(time).getTime() + 1800000 
          let countDown = new Date().getTime()
          let distance = timer - countDown

          let min = Math.floor((distance % (1000*60*60) / (1000*60)))
          let sec = Math.floor((distance % (1000*60) / (1000)))
          //console.log(min, sec)  <<<<< 30 min

          let res = min + ':' + sec
          setTimeOut(res)  // <<< here is conflict 
          },1000)

     return timeOut
 }


我有问题,如果用户作出超过1保留,我有冲突在setTimeOut(res),它将存储2 differencent值在一个位置。
这里有一个问题,我如何修复它?我怎么能自动创建新的计时器和显示它的位置。更多的保留=更多的useState,或任何解决方案。如果你有任何解决方法,请分享。谢啦,谢啦
我希望它是明确的!

68bkxrlz

68bkxrlz1#

这不是在React中使用setInterval的方式。您应该更改代码,以便从setInterval进行的更新触发重新呈现。基本上:

  • formatTime只负责格式化。
  • useEffect调用setInterval,用新格式化的时间周期性地更新状态(setTimeOut)。

它最终应该看起来像这样:

const [timeOut, setTimeOut] = useState('')

const { createdAt } = item

useEffect(() => {
    if (item.status !== 'unPaid') return;

    const timer = window.setInterval(() => {
        setTimeOut(formatTime(createdAt));
    }, 1000);

    return () => window.clearInterval(timer);
}, [createdAt]);

return (
    ...

    <th>{item.status === 'unPaid' ? timeOut : ''} </th>

    ...
)

字符串
我鼓励你创建自己的useInterval钩子,这样你就可以通过使用setIntervaldeclaratively来简化代码,就像Dan Abramov在Making setInterval Declarative with React Hooks中建议的那样。
你可以在我在这里发布的另一个答案中找到解决方案,或者简单地使用我不久前发布的一个库,在那里你可以找到setTimeoutsetIntervaluseTimeoutuseInterval的声明式版本,以及一些用TypeScript编写的附加钩子:https://www.npmjs.com/package/@swyg/corre的函数。

相关问题