我尝试使用
localstorage
获取名为 darkmode
的更新 useContext
状态,但是当我在 App.tsx
内的函数中登录它时,它给出了在 Context.js
内设置的默认值:
App.tsx
const { darkmode } = useContext(Context);
React.useEffect(() => {
console.log(darkmode);
}, []);
上下文.js
import { useState, useEffect, createContext } from "react";
const Context = createContext();
function ContextProvider({ children }) {
const [darkmode, setDarkmode] = useState(false);
// Local Storage: setting & getting data
useEffect(() => {
const darkmode = JSON.parse(localStorage.getItem("darkmode"));
if (darkmode) {
setDarkmode(darkmode);
}
}, []);
useEffect(() => {
localStorage.setItem("darkmode", JSON.stringify(darkmode));
}, [darkmode]);
const toggleDarkmode = () => {
setDarkmode((prev) => !prev);
};
return (
<Context.Provider
value={{
darkmode,
toggleDarkmode,
}}
>
{children}
</Context.Provider>
);
}
export { ContextProvider, Context };
本地存储:
控制台日志:
如何使用 React 上下文获取最新更新的
localstorage
状态?
您遇到的问题是因为
useEffect
中的 App.tsx
在安装组件时仅运行一次,并且它从上下文中记录 darkmode
的初始值。那时,上下文还没有用 localStorage
的值更新。要解决此问题,您可以在 darkmode
的 useEffect
中添加 App.tsx
作为依赖项:
React.useEffect(() => {
console.log(darkmode);
}, [darkmode]);
现在,只要
darkmode
值发生变化,useEffect
就会运行,您应该会在控制台中看到更新后的值。
但是,如果你想避免这种变化导致不必要的重新渲染,你可以使用自定义钩子直接从
darkmode
获取localStorage
的初始值。这样,您可以在上下文提供程序中设置初始值:
在名为
useLocalStorage
的新文件中创建一个名为 useLocalStorage.js
的自定义挂钩:
import { useState, useEffect } from "react";
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.log(error);
return initialValue;
}
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(storedValue));
}, [key, storedValue]);
return [storedValue, setStoredValue];
}
export default useLocalStorage;
现在,在您的
Context.js
中导入并使用此自定义挂钩:
import { useEffect, createContext } from "react";
import useLocalStorage from "./useLocalStorage";
const Context = createContext();
function ContextProvider({ children }) {
const [darkmode, setDarkmode] = useLocalStorage("darkmode", false);
const toggleDarkmode = () => {
setDarkmode((prev) => !prev);
};
return (
<Context.Provider
value={{
darkmode,
toggleDarkmode,
}}
>
{children}
</Context.Provider>
);
}
export { ContextProvider, Context };
现在,您的
App.tsx
应该记录正确的 darkmode
值:
const { darkmode } = useContext(Context);
React.useEffect(() => {
console.log(darkmode);
}, [darkmode]);