Using useContext in React.js

useContext hook allows passing data to children elements without using redux.
useContext is a named export in react so we can importin functional components like below −
import {useContext} from ‘react’;
It’s an easy alternative to Redux if we just need to pass the data to the children elements.
import React, { createContext } from ‘react’;
import ReactDOM from ‘react-dom’;
const MessageContext = createContext();
myApp=()=>{
   return (
      <MessageContext.Provider value=”hello”>
         <div>
            <Test/>
         </div>
      </MessageContext.Provider>
   );
}
In child component Test we can access the message value as below −
Test =()=>{
   return (
      <MessageContext.Consumer >
         {value=><div> message : {value} </div> }
      </MessageContext.Consumer>
   );
}
Note that we have not passed props here in child component. The createContext hooks gives us provider and consumer.
Provider is used to pass the values to child components and child components access the value using consumer as shown above.
This a simple example of consumer but in real life scenarios we may need to have nested consumers. Here we can use useContext to write it in a simple way.
Import { useContext } from ‘react’;
Test =()=>{
   const messageValue=useContext(MessageContext);
   return (
      <div>Message: {messageValue} </div>
   );
}
We eliminated the consumer code and used only useContext which has simplified the code and we can get the values from multiple parents having provider context values. Now, we don’t need to nest the multiple consumers.
useMemo helps in performance optimization. It can execute on every render but only if one of the dependency changes. Similar to useEffect we provide the second argument to useMemo method which we can call as dependency.
useMemo( ()=>{}, [dependency input array]);
the computations in the first function is remembered till the provided dependency are not changed.
If we have lot of heavy computation which should be executed once or executes if one of the input changes, we can use useMemo.
If no input array is provided it will execute on every render. It optimizes the heavy computations in simple words. In the future the advanced compilers will decide the dependency array by itself.
We can replace the useCallback and use only useMemo which works in a similar way.
useCallback(function, []);
useMemo(()=>function body, []);
it caches the function value and returns the same value until one of the dependency changes.
useReducer as name suggest is similar to concept with reducer function in Redux.
It receives a input and based on dispatch action and value it will give us the modified updated state.
const [ state, dispatch]= useReducer((state, action)={
   switch(action.type){
      //calculation based on action type and value
   }
},[]);
We have passed the second argument to useReducer which can be used to set some initial values to state.
import React, { useReducer } from 'react';
function TestNumber() {
   const [total, dispatch] = useReducer((state, action) => {
      return state + action;
   }, 0);
   return (
      <>
         {total}
         <button onClick={() => dispatch(1)}>
            Add 1
         </button>
      </>
   );
}
Here we have initialized state with 0 and incrementing on each click of button.
We have used react fragment <> also in above example.