react-hooks: manage global state - no need of redux
Tags: reacthooks, redux, state, typescript
Published: 2019-06-11 07:11:33

I know You Want to manage global state and using  redux is so 2018.
Remember redux is great but if you don't have a requirenment don't use it at all.
So is there is any way to manage global state without the use of redux.

yes and the answer is "context api" and "useReducer".

In this tutorial you will learn each and every thing you need to manage state globally in series of step.

So lets begin.

In App.tsx

step 1. 
import  React , {useReducer} from “react”;
Great Job!

step 2. 
In your App.tsx call useReducer(countReducer , initialCount) with reducer and initial Count.

oh! no! what the heck is reducer, from where will you get it.

dont't worry reducer is just a function that takes two arguments (state , action)

step 1.5.

So let us create a reducer first okay 

const countReducer = (state, action) => {
  switch (action.type) {
    case "increment":
      return state + 1;
      break;
    case "decrement":
      return state - 1;
      break;
    case "reset":
      return 0;
      break;
    default:
      return 0;
      break;
  }
};
const initialCount = 0;

omg you have just created reducer and initial state 
isn't it fun

step 2 again.

call useReducer with countReducer and initialCount.
and you will get current state and a dispatch method which will call reducer we create above.

const [countState, countDispatch] = useReducer(countReducer , initialCount);
useReducer take two arguments 

you might have one question why you use that ugly array kind of thing.
believe me it is just syntaxtic sugar When i saw this i have the same feeling.

so basically it is array destructing.
It is not array just two normal variables

instead of writing 
const countState = blablabla and 
const  countDispatch = blablabla

i wrote const [countState, countDispatch] = blablabla

it is just neat and clean

useReducer returns an array of two elements 
state  --- represent current state
dispatch  method -- to dispatch actions in reducer


step 2 complete take some rest.

step 3 create context.
for this first import createContext from react

import React, { useReducer, createContext } from "react";
and create context.

export const CounterContext = createContext(null);




















We can pass dispatch method from one component to another through context.Provider and update global state .

In first file
import React, { useReducer, createContext } from "react";
const initialState = 0;
export const CounterContext = createContext(null);
const App: React.FC = () => {
 const [count, dispatch] = useReducer(countReducer, initialState);
 return (
   <div>
     <CounterContext.Provider value = {{count, dispatch}}>
       <Counter />
     </CounterContext.Provider>
     Count: {count}
);
};
export default App;
In second file
import React, { useContext } from "react";
import { CounterContext } from "./App";
export const Counter = () => {
 const context = useContext(CounterContext);
 return (
   <div>
     <h1>{context.count}</h1>
     <button onClick={() => context.dispatch({ type: "increment" })}>+</button>
     <button onClick={() => context.dispatch({ type: "decrement" })}>-</button>
     <button onClick={() => context.dispatch({ type: "reset" })}>0</button>
     <h2>-----------------</h2>
   </div>
 );
};