DEV Community

Discussion on: Add Offline-Caching to Your React Reducer with 5 Lines of Code

rakannimer profile image
Rakan Nimer Author • Edited on

Thanks for taking the time to write that !

The main reason I didn't go into it, is to keep the code under 5 lines 😅

I wanted the reader to quickly understand the idea of using HOFs with the reducer and build on it and experiment themselves.

Now they can also read/use this hook 👌

Thread Thread
bionicles profile image
bion howard • Edited on
// src/state/hook.jsx

import React, { createContext, useContext, useReducer, useMemo } from "react";
import { reduce, logger, initialState } from "state";

const LOGGING = 1;

export const StateContext = createContext();

export const withCache = reducer => (s, a) => {
  const newS = reducer(s, a);
  localStorage.setItem("state", JSON.stringify(newS));
  return newS;
};

export const StateProvider = ({ children }) => {
  const [state, dispatch] = useReducer(
    withCache(LOGGING ? logger : reduce),
    JSON.parse(localStorage.getItem("state")) || initialState
  );
  const value = useMemo(() => {
    return { state, dispatch };
  }, [state, dispatch]);
  return (
    <StateContext.Provider value={value}>{children}</StateContext.Provider>
  );
};

export const useState = () => useContext(StateContext);
// src/app.js
import { StateProvider } from "state";

... layout stuff ...

const App = () => (
  <StateProvider>
    <Layout />
  </StateProvider>
);

export default App;
// src/components/my-component.jsx
import React from "react";
import { useState } from "state";

const MyComponent = props => {
    const { state: { thingy }, dispatch } = useState();
    return // my jsx
}
// src/state/index.js
export * from "state/initial-state";
export * from "state/reduce";
export * from "state/logger";
export * from "state/hook";