如何在 React 上下文中使用本地存储的更新状态?

问题描述 投票:0回答:1

我尝试使用

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
状态?

javascript reactjs local-storage react-context
1个回答
0
投票

您遇到的问题是因为

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]);
© www.soinside.com 2019 - 2024. All rights reserved.