提问者:小点点

react中页面刷新时丢失组件数据


我正在做一些需要维护应用程序级别状态(即全局状态)的事情,我正在为UseContextUserEducer使用react钩子。

因此,我所做的就是单击按钮,设置上下文,然后通过在app.js中注册提供程序来使用它。

我知道为什么我要使用我的数据,因为我首先将初始状态设置为null,这就是为什么当我刷新页面时,它再次设置为null,但我的要求不是在按钮单击之后,我想要将数据存储为全局状态,以便我可以进一步使用它

但这不应该是这样的情况我想使我的数据是全局的,并且在刷新时它不应该丢失

我的代码

我的上下文文件

import React, { useReducer, createContext } from "react";

const initialstate = {
  someData: null
};

const MyContext = createContext({
  someData: null,
  click_btn: d => {}
});
const MyReducer = (state, action) => {
  switch (action.type) {
    case "BTNCLICKED":
      return {
        ...state,
        someData: action.payload
      };

    default:
      return state;
  }
};

const MyProvider = props => {
  const [state, dispatch] = useReducer(MyReducer, initialstate);
  const click_btn = d => {
    dispatch({
      type: "BTNCLICKED",
      payload: d
    });
  };

  return (
    <MyContext.Provider
      value={{ someData: state.someData, click_btn }}
      {...props}
    />
  );
};

export { MyContext, MyProvider };

我正在设置上下文的主代码

    import React, { useContext, useState } from "react";
import history from "../History/history";

import { MyContext } from "../context/testContext";

function Test() {
  const context = useContext(MyContext);
  const [data, setdata] = useState(null);
  const clickEvt = () => {
    setdata("Setting data");
    context.click_btn(data);
  };
  return (
    <div>
      <input type="button" onClick={clickEvt} value="Click Me" />
    </div>
  );
}

export default Test;

和我的app.js文件

    import React from "react";
import "./styles.css";
import { MyProvider } from "./context/testContext";
import { Router } from "react-router-dom";
import history from "./History/history";
import Routes from "./myRoutes";

export default () => {
  return (
    <MyProvider>
      <Router history={history}>
        <div className="App wrapper">
          <Routes />
        </div>
      </Router>
    </MyProvider>
  );
};

请检查工作代码,我的代码和框链接

请检查react developer工具


共2个答案

匿名用户

缺少持久性机制。 您可以扩展MyProvider函数,以便它从LocalStorage或api获取值

API示例


const MyProvider = props => {
  const [state, dispatch] = useReducer(MyReducer, initialstate);
  const click_btn = payload => {
    saveStateToApi(payload)
      .then(result => {
         dispatch({
           type: "BTNCLICKED",
           payload
         });
      })
  };

  useEffect(() => {
    getLastStateFromApi()
      .then(data => {
        dispatch({
          type: "BTNCLICKED",
          payload: data
        });
      })

  }, [])

  return (
    <MyContext.Provider
      value={{ someData: state.someData, click_btn }}
      {...props}
    />
  );
};

匿名用户

要持久化React上下文,redux存储或任何存在于应用程序内存中的内容,您需要将其存储在外部,然后在应用程序启动时重新加载(当您按F5键时,页面将被刷新,React应用程序将被重新启动,因此它将丢失所有组件状态,上下文,存储。。。)。

例如,您可以将上下文保存在本地存储中,并修改上下文,使其从搜索存储值开始,然后首先重新加载它。 它可以在您的上下文中使用useEffect来完成:每次更改时,将其存储在本地存储中,并在启动时预加载本地存储值:

// context
[...]

useEffect(() => {
  if(localStorage.getItem('myKey')) {
    setState(localStorage.getItem('myKey');
  }
}, []);

useEffect(() => {
  localStorage.setItem('myKey', state);
}, [state]);

这就是它的大致实现方式,它可以使用重构。

您也可以选择在远程服务器或本地noSQL DB上持久化上下文。 你会有很多解决方案:

  • https://medium.com/@akrush95/global-cached-state-in-react-using-hooks-context-and-local-storage-166eacf8ab46
  • https://github.com/aprilmintacpineda/react-context-api-store
  • https://www.robinwieruch.de/local-storage-react
  • https://dev.to/selbekk/persisting-your-react-state-in-9-lines-of-code-9go
  • 。。。