在刷新时反应挂钩和上下文api localstorage

时间:2020-06-29 15:05:29

标签: javascript reactjs local-storage

在我的SPA中,我正在使用反应挂钩和上下文API。我需要保留使用上下文API渲染的组件视图的当前状态,以便可以通过应用程序实现全局组件条件渲染。

我在一个仪表板页面上有两个视图:概述和详细信息。该按钮会触发全局状态更改,并且即使在刷新页面时也应将视图固定在状态值上。

这是我的代码段:

AppRoutes文件

import React, { useState } from "react";
import { Router, Route, Switch } from "react-router-dom";
import history from "../utils/history";
import { PyramidProvider } from "../context/pyramidContext";

import Dashboard from "../pages/dashboard/Dashboard";

const AppRoutes = () => {

  return (
    <div>
      <React.Suspense fallback={<span>Loading...</span>}>
          <Router history={history}>
            <Switch>
              <PyramidProvider>
                <Route path="/" component={Dashboard} />
              </PyramidProvider>
            </Switch>
          </Router>
      </React.Suspense>
    </div>
  );
};

export default AppRoutes;

仪表板页面

import React, { useState, useEffect, useContext } from "react";
import { PyramidContext } from "../../context/pyramidContext";
import PyramidDetail from "../../components/pyramidUI/pyramidDetail";
import PyramidOverview from "../../components/pyramidUI/pyramidOverview";

const Dashboard = (props) => {
  const { info, setInfo } = useContext(PyramidContext);
  return (
    <React.Fragment>
      {info.uiname === "overview" ? <PyramidOverview /> : <PyramidDetail />}
    </React.Fragment>
  );
};

export default Dashboard;

概述组件

import React, { useState, useContext } from "react";
import { PyramidContext } from "../../context/pyramidContext";

const Overview = (props) => {
  const { info, setInfo } = useContext(PyramidContext);

  return (
    <div className="d-flex flex-column dashboard_wrap">
      <main>
        <div className="d-flex">
          <button
            onClick={() => setInfo({ uiname: "detail", pyramidvalue: 1 })}
          >
            change view
          </button>
        </div>
      </main>
    </div>
  );
};

export default Overview;

详细信息组件

import React, { useContext } from "react";
import { PyramidContext } from "../../context/pyramidContext";
// import axios from "axios";

const Detail = (props) => {
  const { info, setInfo } = useContext(PyramidContext);

  return (
    <div className="d-flex flex-column dashboard_wrap">
      <h2>Detail View</h2>
      <div>
        <button
          type="button"
          onClick={() => setInfo({ uiname: "overview", pyramidvalue: 0 })}
        >
          Back
        </button>
      </div>
    </div>
  );
};

export default Detail;

上下文文件

import React, { createContext, useEffect, useReducer } from "react";
let reducer = (info, newInfo) => {
  return { ...info, ...newInfo };
};
const initialState = {
  uiname: "overview",
  pyramidvalue: 0,
};
const localState = JSON.parse(localStorage.getItem("pyramidcontent"));
const PyramidContext = createContext();
function PyramidProvider(props) {
  const [info, setInfo] = useReducer(reducer, initialState || localState);
  useEffect(() => {
    localStorage.setItem("pyramidcontent", JSON.stringify(info));
  }, [info]);
  return (
    <PyramidContext.Provider
      value={{
        info,
        setInfo,
      }}
    >
      {props.children}
    </PyramidContext.Provider>
  );
}
export { PyramidContext, PyramidProvider };

我单击按钮以呈现detail视图,刷新页面后,组件将其视图更改为overview而不是停留在detail上。我检查了本地存储值,并已对其进行了正确更新,但是仍然无法按照该值持久保存组件视图。

我无法理解我在哪里做错了,请帮忙解决此问题?预先感谢。

1 个答案:

答案 0 :(得分:2)

您永远不会在信息状态下使用localStage的值, 您应该将代码替换为:

const [info, setInfo] = useReducer(reducer, localState || initialState);