Ale*_*drs 5 javascript typescript reactjs next.js
我试图localstorage在 NextJS 中实现钩子,但出现以下错误:Error: Hydration failed because the initial UI does not match what was rendered on the server.。有什么想法可能导致它吗?在我看来,该功能似乎useEffect没有正确使用。如何强制使用 CSR 而不是 SSR 以避免水合错误?
import { useState, useEffect } from 'react';
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
if (typeof window === 'undefined') {
return initialValue;
}
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
useEffect(() => {
setStoredValue(storedValue);
}, [storedValue, setStoredValue]);
// eslint-disable-next-line no-unused-vars
const setValue = (value: T | ((val: T) => T)) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
if (typeof window !== 'undefined') {
window.localStorage.setItem(key, JSON.stringify(valueToStore));
}
} catch (error) {
console.log(error);
}
};
return [storedValue, setValue] as const;
}
export default useLocalStorage;
Run Code Online (Sandbox Code Playgroud)
小智 1
我知道有两种方法可以消除水合错误。
首先是使用 next/dynamic 并通过 ssr 选项传递为 false 动态加载,如下所示:
import dynamic from 'next/dynamic'
const DynamicHeader = dynamic(() => import('../components/header'), {
ssr: false,
})
Run Code Online (Sandbox Code Playgroud)
但由于这是一个自定义挂钩,我们只能动态导入 Component,因此在这种情况下您必须正确使用 useEffect!
其次是使用 useEffect 钩子。我已经在 Js 中做到了这一点希望这有帮助!
import { useEffect, useState } from "react";
export default function useLocalStorage(key, initialValue) {
const [value, setValue] = useState();
useEffect(() => {
const data = localStorage.getItem(key);
if (data === null) {
if (typeof initialValue === "function") {
setValue(initialValue());
} else {
setValue(initialValue);
}
} else {
setValue(JSON.parse(data));
}
}, []);
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [value]);
return [value, setValue];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4373 次 |
| 最近记录: |