简体   繁体   中英

React hooks and context api localstorage on refresh

In my SPA, I am utilizing react hooks and context API. I need to persist the current state of the component view rendered using the context API so that I can implement the global component conditional rendering through the application.

I have two views on a single dashboard page: overview & detail. The button triggers the global state change and the view should be fixed on the state value even on page refresh.

Here's my code snippets:

AppRoutes file

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;

Dashboard page

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;

Overview component

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;

Detail component

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;

Context File

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 };

I click the button to render a detail view and soon as the page is refreshed, the component changes its view to overview instead of sticking around to detail . I checked the local storage values, and it is being updated properly, but still, the component view does not persist as per the value.

I am unable to understand where I am doing wrong, any help to resolve this issue, please? Thanks in advance.

You're never using the value of localStage in your info state, you should replace your code with:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM