24
loading...
This website collects cookies to deliver better user experience
Provider
serves the values:import React from 'react';
const StateContext = React.createContext(/* default state */);
const App = props => (
<StateContext.Provider value={{ color: green }}>
{props.children}
</StateContext.Provider>
);
Consumer
uses the values:const ConsumerComponent = () => (
<StateContext.Consumer>
{value => (
<Button primaryColor={{ value.color }}>Consumer</Button>
)}
</StateContext.Consumer>
);
functional components
. There are other ways to access context values in class-based components. You may read up on those in the official React docshooks
were introduced and things were never the same again. It was not just state management that benefited but React in its entirety saw a much-needed overhaul from all the classes that we used to write previously.useReducer
hook can be used to set up Context API within our app. The useReducer hook takes 2 arguments; namely a reducer function
and an initial state
:import React, { useReducer } from 'React';
const reducer = (state, action) => {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
return state;
}
};
const IncrementComponent = ({ initialCount }) => {
const [state, dispatch] = useReducer(reducer, { count: 0 }); return (
<button onClick={() => dispatch({ type: 'increment'})}>
Increment: {state.count}
</button>
);
} ;
[state, dispatch]
array where state
is the current state you can consider dispatch
to be like a gun that shoots actions at our data layer. You can call it anything but while looking at a Redux substitute, we can use its naming convention at the very least!dispatch
method is called, the reducer function is triggered which matches your action type and updates the state as per the payload you send to it.import React , { createContext , useContext , useReducer } from 'react';
export const StateContext = createContext();
export const StateProvider=({ reducer , initialState , children })=>(
<StateContext.Provider value = {useReducer(reducer,initialState)}>
{children}
</StateContext.Provider>
);
export const useStateValue = () => useContext(StateContext)
createContext
creates a context object and returns it to StateContext which stores the Provider
and the Consumer
useStateValue
which is a custom hook
which uses the StateContext context
. We did this because otherwise you would have to import useContext
and StateContext
in all places wherever you wanted access to these values. Building up on the DRY principle of coding, we created a universal hook to take care of the same once and for all.StateProvider
component. We already took a look at what a reducer
could look like earlier. The initial state
can be anything you want; a JSON object, an array, or whatever fits your purposes the best.StateProvider
component and we're all set. In our entry file (generally App.js), we just need to wrap our return block with the StateProvider =>import { StateProvider } from './utils/StateProvider';
import reducer, { initialState } from './utils/reducer';
const App = () => {
return (
<StateProvider initialState={initialState} reducer={reducer}>
// Content ...
</StateProvider>
);
}
import { useStateValue } from '../utils/StateProvider'
const MyComponent = () => {
const [state, dispatch] = useStateValue()
}
useStateValue
under the hood use the useContext
hook and the rules of hooks clearly state that hooks can only be called inside the body of a functional component
.
If you want to use these values in a class-based component
, you shall have to go over the bit more verbose method of using Consumer or contextType
but in modern times, working with functional components is the norm and there's no way that this implementation shall break any time in the future.