updated July 05, 2024331 views

Tôi đang tạo một chức năng Dark/Light Mode trên ứng dụng của mình bằng NextJs và đây là một phần của đoạn code của tôi:

import * as React from 'react'

import { useColorMode, Button } from 'theme-ui'

import { Sun, Moon } from 'phosphor-react'

import { VisuallyHidden } from '@reach/visually-hidden'



const ColorModeToggle: React.FC = () => {

	const [colorMode, setColorMode] = useColorMode()



	return (

		<Button

			variant="color-mode-toggle"

			onClick={()=> {

				setColorMode(colorMode= 'default' ? 'dark' : 'default')

			}}

		>

			<VisuallyHidden>Toggle color mode</VisuallyHidden>

			{colorMode === 'default' ? <Sun weight="bold" /> : <Moon weight="bold" />}

		</Button>

	)

}



export default ColorModeToggle

Nó hoạt động tốt đúng như kỳ vọng của tôi. Nhưng khi tôi mở cửa sổ Developer Tools của trình duyệt thì nhận được lỗi khá khó chịu này: Warning: Expected server HTML to contain a matching <circle> in <svg> bạn có thể xem hình dưới đây:

Warning: Expected server HTML to contain a matching ... in ...

Nếu tôi click chuột vào react-dom.development.js:67 thì tôi sẽ thấy lỗi sau:

Warning: Expected server HTML to contain a matching %s in %s.%s

Nếu tôi xóa cookie trên trình duyệt, tôi sẽ không gặp lỗi trên. Như vậy, tôi hiểu rằng một đoạn HTML nào đó được hiển thị trên trình duyệt không khớp với đoạn HTML được tạo trên phía server. Hướng giải quyết là ta sẽ cập nhật trạng thái trong userEffect như sau:

import * as React from 'react'

import {useState, useEffect} from 'react'

import { useColorMode, Button } from 'theme-ui'

import { Sun, Moon } from 'phosphor-react'

import { VisuallyHidden } from '@reach/visually-hidden'



const ColorModeToggle: React.FC = () => {

	const [colorMode, setColorMode] = useColorMode()



	const [mounted, setMounted] = useState(false);

	useEffect(() => {

		setMounted(true)

	}, [])



	return ( mounted &&

		<Button

			variant="color-mode-toggle"

			onClick={()=> {

				setColorMode(colorMode= 'default' ? 'dark' : 'default')

			}}

		>

			<VisuallyHidden>Toggle color mode</VisuallyHidden>

			{colorMode === 'default' ? <Sun weight="bold" /> : <Moon weight="bold" />}

		</Button>

	)

}



export default ColorModeToggle

Tham khảo thảo luận trên githubstackoverflow.