Build a Simple Redux from Scratch and Integrate It with React

This article explains Redux’s core concepts, demonstrates how to implement a basic createStore function in JavaScript, and shows how to integrate it with React using a custom Provider and connect higher‑order component for state sharing across components.

KooFE Frontend Team
KooFE Frontend Team
KooFE Frontend Team
Build a Simple Redux from Scratch and Integrate It with React

Redux is a popular state management tool that stores the entire application state in a single place for centralized management. This article implements a simple Redux from scratch.

Core concepts of Redux

The entire application state is stored in a single store.

The only way to change state is by dispatching actions.

Reducers describe how actions transform the state.

Store API

getState() – retrieve the current state.

dispatch(action) – update the state.

subscribe(listener) – register a listener.

The function returned by subscribe can unsubscribe the listener.

Implementing createStore

const createStore = (reducer, preloadedState) => {
  let state = preloadedState;
  const listeners = new Set();
  // dispatch(action) updates state
  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };
  // getState() returns state
  const getState = () => state;
  // subscribe registers a listener
  const subscribe = (listener) => {
    listeners.add(listener);
    return unsubscribe(listener);
  };
  // unsubscribe removes a listener
  const unsubscribe = (listener) => () => {
    listeners.delete(listener);
  };
  return { dispatch, subscribe, getState };
};

Using the store

const reducer = (state = { count: 0 }, action) => {
  switch (action.type) {
    case "increment":
      return { count: state.count + 1 };
    case "decrement":
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
};
const store = createStore(reducer);
const unsubscribe = store.subscribe(() => {
  const state = store.getState();
  console.log(state.count);
});
store.dispatch({ type: "increment" });
unsubscribe();

Integrating with React

The store can be used in React components; when the store changes, components are forced to re‑render.

const Counter = () => {
  const [, forceUpdate] = React.useState();
  useEffect(() => {
    const unsubscribe = store.subscribe(() => {
      forceUpdate({});
    });
    return () => {
      unsubscribe();
    };
  }, []);
  return (
    <div onClick={() => store.dispatch({ type: "increment" })}>
      {store.getState()?.count || 0}
    </div>
  );
};

Simple React‑Redux implementation

First, define a Provider component using React Context to share the store.

const ReduxContext = React.createContext();
const Provider = ({ store, children }) => {
  const contextValue = useMemo(() => ({ store }), [store]);
  return (
    <ReduxContext.Provider value={contextValue}>
      {children}
    </ReduxContext.Provider>
  );
};

Then, create a connect higher‑order component that maps store state and dispatch to component props and forces a re‑render when the store updates.

const connect = (mapStateToProps, mapDispatchToProps) => {
  return (Component) => {
    return (props) => {
      const [, forceUpdate] = useState({});
      const { store } = useContext(ReduxContext);
      const stateToProps = mapStateToProps(store.getState());
      const dispatchToProps = mapDispatchToProps(store.dispatch, props);
      useEffect(() => {
        const unsubscribe = store.subscribe(() => {
          forceUpdate({});
        });
        return () => {
          unsubscribe();
        };
      }, [store]);
      return <Component {...props} {...stateToProps} {...dispatchToProps} />;
    };
  };
};

Usage example:

const Counter = (props) => (
  <div onClick={props.onClick}>{props.count}</div>
);
const CounterWrap = connect(
  state => ({ count: state.count }),
  dispatch => ({
    onClick: () => {
      dispatch({ type: "increment" });
    }
  })
)(Counter);
const App = () => (
  <Provider store={store}>
    <CounterWrap />
  </Provider>
);
frontendJavaScriptReduxState ManagementReActtutorial
KooFE Frontend Team
Written by

KooFE Frontend Team

Follow the latest frontend updates

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.