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:
Nếu tôi click chuột vào react-dom.development.js:67 thì tôi sẽ thấy lỗi sau:
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 github và stackoverflow.