簡體   English   中英

為什么使用React Hooks,MomentJS對象和時間間隔/超時更新狀態不會觸發重新渲染?

[英]Why does updating state using React Hooks, MomentJS object and interval/timeout not trigger re-render?

我正在嘗試使用React-Native,React Hooks,MomentJS和(setTimeout / setInterval)制作一個倒數計時器。 無論我嘗試使用哪種方法,它都會失敗。 問題在於該組件永遠不會重新呈現。

我嘗試遵循React Hooks的官方文檔,在Medium上寫了幾篇文章,例如React Hooks的Iceberg,但沒有任何效果。

一種可能是它需要MomentJS對象的深層克隆,但是我猜這是一種低效的方法。

這是我嘗試過的可復制示例之一。

const Timer = () => {
  const [time, setTime] = useState(moment.duration(30, 'seconds'))
  const intervalRef = useRef()

  useEffect(() => {
    intervalRef.current = setTimeout(() => {
      setTime(prevTime => prevTime.subtract(1, 'second'))
    }, 1000)

    return () => {
      clearInterval(intervalRef.current)
      intervalRef.current = null
    }
  })

  return (
    <View>
      {time.asSeconds()}
    </View>
  )

一種可能是它需要MomentJS對象的深層克隆,但是我猜這是一種低效的方法。

對,就是這樣。 如果當前狀態和先前狀態相等,則React不會重新渲染。 您可以只將秒存儲在狀態中。

而且您不需要那個參考。

const Timer = () => {
  const [time, setTime] = useState(30 /*s*/)

  useEffect(() => {
    const timeout = setTimeout(() => {
      setTime(prevTime => prevTime - 1);
    }, 1000)

    return () => clearTimeout(timeout);
  }, [time])

  return (
   <View>
     {time}
   </View>
 );

您是正確的,它不是重新渲染,因為您的矩對象在每個刻度上都是相同的(但發生了突變)。 您可以通過在setTime更新程序中添加.clone()輕松地使其工作:

const Timer = () => {
  const [time, setTime] = useState(moment.duration(30, "seconds"));
  const intervalRef = useRef();

  useEffect(() => {
    intervalRef.current = setTimeout(() => {
      setTime(prevTime => prevTime.clone().subtract(1, 'second'))
    }, 1000)

    return () => {
      clearInterval(intervalRef.current)
      intervalRef.current = null
    }
  })

  return <div>{time.asSeconds()}</div>;
};

此處的工作沙箱: https//codesandbox.io/s/gifted-euler-e8xg5

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM