Hey! I'm on a mission to make 100 React.js projects ending March 31st. Please follow my dev.to profile or my twitter for updates and feel free to reach out if you have questions. Thanks for your support!
Link to the deployed project: Link
Link to the repo: github
I'm going back to my Scrimba (thank you Scrimba 🙏) React tutorial and starting from the beginning of the Context API section I abandoned quite a while ago. It's funny that I've built so many React projects without Context or Redux. I guess it just shows I haven't built many production-level web applications with tens or hundreds of components, but even the full-stack applications I have built have avoided complex state management tools like these by passing props 🤔
So this is one of the simplest projects you could do with Context, but it's a worthwhile exercise for someone new to it because it's so demonstrative of the tool, and how it is working.
We start out with a create-react-app
project and remove all of the contents of the App
component. Next I create a React component and call it Prompt
. This is where we'll ask for some user input. I actually stored my state in the App
component despite Prompt
being where we take in data which just goes to show how used to the props way of doing things that I am. Apparently, any component can serve as the provider of data.
import React,{useState} from 'react'
import Prompt from './components/Prompt'
import InnerOne from './components/InnerOne'
import NameContext from './nameContext'
function App() {
const [name,setName] = useState('')
const handleNameChange = (e) => {
setName(e.target.value)
}
return (
<div className="app">
<Prompt handleNameChange={handleNameChange} />
<NameContext.Provider value={name}>
<InnerOne />
</NameContext.Provider>
</div>
);
}
export default App;
According to React master Kent C. Dodds all we need to do is "use the Provider and expose a component that provides a value".
To actually begin using the Context API it's a best practice to have a separate file where you initialize the context so that it can be imported and used anywhere. We can do this in just two lines of code by importing {createContext} from the React node module and initializing a new context. Then you'll have to export it.
import {createContext} from 'react'
const NameContext = createContext()
export default NameContext;
As you can see above in the App
component we then import this context to create a Provider.
import NameContext from './nameContext'
...
<NameContext.Provider value={name}>
<InnerOne />
</NameContext.Provider>
We can then pass any information we want to other components by creating props on the Provider. I then create a component called InnerOne. This is basically just a div with a little styling but the fact that we're creating a separate component will demonstrate what's going on with Context. I will also create an InnerTwo
component with the same structure.
import React from 'react'
import InnerTwo from './InnerTwo'
const InnerOne = () => {
return (
<div className='innerOne inner-container'>
Inner One - I have no context
<InnerTwo />
</div>
)
}
export default InnerOne
InnerThree
is where the action is. Here is where we actually create a consumer to use the data provided by the provider. It has access to the data in the provider despite being nested two levels deep and not having any props!
import React from 'react'
import NameContext from '../nameContext'
const InnerThree = () => {
return (
<NameContext.Consumer>
{(name) => (
<div className='innerThree inner-container'>
Inner three - Do I have some context? 🤔
<div className='innerThree__nameText'>{name}</div>
</div>
)}
</NameContext.Consumer>
)
}
export default InnerThree
Like I said, not the fanciest project but I do feel it's deeply illustrative of the power of React Context. You can extrapolate this relationship to any depth. 100 levels deep and you could still pass that data from the provider without props.
Neat! More context tomorrow. If you like projects like this don't forget to follow me on the Twitters :)
Top comments (0)