Copyright © 2008 ~ 2024 MUKI space* / omegaBook theme All Rights Reserved.

錯誤原因

如果你在渲染 HTML 時,碰到類似的錯誤:Text content did not match.,然後會分別告訴你 Server 以及 Client 端的值是什麼,如果當兩個值不一樣時,就會出現這個警告。

會出現這錯誤,是因為 Next.js 會先在 Server 端預先渲染頁面,在瀏覽器載入頁面時,再透過執行 JavaScript 讓頁面互動。因此,當在瀏覽器上渲染的 HTML 與在伺服器上產生的 HTML 不相符時,就會出現這個錯誤。

而我的這個情況,是使用了 new Date() 導致在 Sever 端以及 Client 端會有微小的差異,透過 warning 畫面,可以看到差了 4 秒,因此導致這個錯誤。

▼ 我原本的寫法

const Page = () => {
  const [lastUpdated, setLastUpdated] = useState<Date>(new Date)
  return(
  <>
    {lastUpdated}
  </>
  )
}

解決辦法

▼ 我們可以阻擋一些元件,讓他們不要在 Server 端渲染,這部分可以使用 useEffect() 處理

const Page = () => {
  const [hydrated, setHydrated] = useState(false)
  const [lastUpdated, setLastUpdated] = useState<Date>()
  
  useEffect(() => {
    setHydrated(true)
  }, [])

  useEffect(() => {
    if (hydrated) {
      setLastUpdated(new Date())
    }
  }, [hydrated])

  if (!hydrated) return null
  
  return(
  <>
    {lastUpdated}
  </>
  )
}

我們在 useEffect() 傳遞了一個空的陣列,讓函數只會在第一次掛載時被調用,先用 hydrated 阻止日期被渲染,所以 Server 端在渲染時會排除日期,在 Client 渲染時,因為 hydrated 初始化是 false,所以第一次掛載也不會渲染日期,直到 hydrated 變成 true 才會執行 setLastUpdate(new Date())

用這個方法,就能有效處理渲染不同步的問題,下次如果碰到一樣的狀況,可以試試看該方法唷。

參考資料

歡迎給我點鼓勵,讓我知道你來過 :)

2
Subscribe
Notify of
guest

0 則留言
Inline Feedbacks
View all comments