Should I use Redux or Context API?

·

4 min read

In React application, we can pass values from a parent to a child component through props. The issue comes up when the relationship between parent and child components is way too deep, where a nested child component needs values from the parent. Yes, we can pass the values through props, also known as props drilling (even though it is quite painful to deal with), but this will cause the values to be exposed to the other components where these components do not need those values. Besides, deeply nested prop drilling can cause unnecessary re-rendering and definitely, impacts user experience as a whole (absolutely a no!).

To avoid those pitfalls, we can use a global state management solution, like Redux or Context API. But which one is most suitable for our application?

Context API

Context API is a built-in feature from React, so it does not impact the size of the final bundle of the application. For example, we have a React application and some components need to consume the locale preference of the user. To do this with Context API, we can start by:

  1. Create a context with English or "EN" as the default value

     import { createContext } from 'react';
    
     const LocaleContext = createContext({
         locale: 'EN',
     });
    
  2. Use the provider to let the tree of the component use the values

     const LocaleProvider = ({ children }) => (
         <Context.Provider value={value}>
             {children}
         </Context.Provider>
     );
    
  3. By leveraging useContext, the particular component can consume the data directly from Context

     import { useContext } from "react";
    
     const Sidebar = () => {
         const { locale } = useContext(LocaleContext);
    
         return (
             // use the value
         );
     };
    

Redux

Redux is an open-source library, that provides a centralized store so that the components across the application can consume the values, and by using action dispatch to update the state. By using a similar example as above, we can apply this with Redux

  1. Install Redux and react-redux

     yarn add redux react-redux
    
  2. Create reducer

     export const LOCALE_ACTION_TYPES = {
       SET_LOCALE: "SET_LOCALE",
     };
    
     const INITIAL_STATE = {
       locale: "EN",
     };
    
     export const localeReducer = (state = INITIAL_STATE, action) => {
       const { type, payload } = action;
    
       switch (type) {
         case LOCALE_ACTION_TYPES.SET_LOCALE:
           return {
             ...state,
             locale: payload,
           };
         default:
           return state;
       }
     };
    

    Here we have the initial state and assign it as the default parameter of the state in localeReducer function. Depending on the action type, it makes changes to the state and returns the freshly updated state. If no action type matches, then it just returns the original state.

  3. Create the store and provider

     import { createStore } from "redux";
     import { cartReducer } from "./reducers/localeReducer";
    
     const store = createStore(localeReducer);
    
     export default store;
    

    From here the store can supply values to components by wrapping child components with <Provider> tag that we can get from the react-redux library.

     import { Provider } from "react-redux";
     import { store } from "./store/store";
    
     render (
         <Provider store={store}>
             <App />
         </Provider>
     );
    
  4. Access the store with useSelector

    Import the useSelector hook from react-redux library so that we can access the store and consume its values.

     import { useSelector } from "react-redux";
    
     const state = useSelector((state) => state);
     // rest of the code
    
  5. Dispatch action with useDispatch

     import { useDispatch } from "react-redux";
    
     const App = () => {
       const dispatch = useDispatch();
    
       useEffect(() => {
         dispatch(actionHere);
       }, [dispatch]);
    
         // rest of the code
     };
    

The Verdict

My thoughts would be depending on how large and complex the app is. We can grasp the idea that Context API is suitable for simple applications while Redux is more towards complex applications. Context API is specifically designed for static data that is not periodically updated, while Redux truly shines working with both static and dynamic data.

In addition to this, Redux requires a long setup process to integrate to React application, but it is extendable because adding new actions is easy after the initial setup. So, Redux is overkill only for the sake of passing props from parent to child, while Context API is excellent in this case.