Implementation of createContext using custom hooks

Unni Krishnan D
3 min readMay 6, 2022

--

Prerequisites

React knowledge

Why we need context ?

Sharing of data across components with out the use of any state management libraries like redux or other storages like localStorage.

The code

Assuming we have scaffolded a basic reactjs app using create-react-app

Create a context (MyContext.jsx) in src/context folder

import React, { useState } from "react";
const MyContext = React.createContext();
const defaultValue = {
name: "No name defined",
weapon: "No weapon defined"
};
export const MyContextProvider = ({ children, initialData }) => {const [value, setValue] = useState(initialData || defaultValue);const saveValue = (values) => { setValue(values) };return (
<MyContext.Provider value={{ avengerData: value, saveValue }}> {children}
</MyContext.Provider>
);
};
export default MyContext;

we have a state variable (value)and it change modifier (setValue) defined. Using context we are providing the value and the modifier function to its children.

Now lets create a custom hook (userAvengers.js) in src/hooks and import the above context in the hook

import { useContext } from "react";
import MyContext from "../context/MyContext"; // import the context
const UseAvenger = () => {
const context = useContext(MyContext);
return context;
};
export default UseAvenger;

Now we can use this context. Here im using this context for the entire application so I'm modifying my src/index.js like this

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { MyContextProvider } from './context/MyContext';
const root = ReactDOM.createRoot(document.getElementById('root'));const defaultValue = {name: "Captain America",weapon: "Shield"};root.render(
<MyContextProvider initialData={defaultValue}>
<App />
</MyContextProvider>
);

Here we have wrapped the entire application <App /> in MyContextProvider and passed a default value as initialData to the context provider

In App.jsx we consumed the context using the custom hook useAvengers and we used one more component AnotherComponent which modifies the context data

App.js

import UseAvenger from './hooks/useAvengers';
import AnotherComponent from './components/AnotherComponent';
function App() {
const { avengerData } = UseAvenger();
return (
<div style={{border:'2px solid #F8C565', padding:'5px', margin:'5px'}}>
<p>The current Avenger is <strong>{avengerData.name}</strong>, and the weapon is <strong>{avengerData.weapon}</strong></p><AnotherComponent />
</div>
);
}
export default App;

AnotherComponent.jsx

import UseAvenger from '../hooks/useAvengers';
import React, {useEffect} from 'react';
function AnotherComponent() {
const { avengerData, saveValue } = UseAvenger();
const changeAvengers = () => {saveValue({ name: "Tony stark", weapon: "Arc" });
};
return (
<div style={{border:'2px solid #e3e3e3', padding:'5px', margin:'5px'}}>
<strong>Another component</strong>
<p>The current Avenger is <strong>{avengerData.name}</strong>, and the weapon is <strong>{avengerData.weapon}</strong></p><div><button onClick={() => {changeAvengers()}}>Change</button>/div></div>);
}
export default AnotherComponent;

When we click on the change button we are calling the changeAvengers function which in turn calls the saveValue function which is a context provider functionality that modifies the context data. When the data is successfully modified both the App and AnotherComponent will gets the new data.

Initial load we get the following data

After clicking change

Conclusion

A robust way of sharing data across components if you are not using any state management libraries or you have a lot of nested components to pass the props.

--

--

Unni Krishnan D
Unni Krishnan D

Written by Unni Krishnan D

Declare variables , not war! 😎

No responses yet