Reputation: 794
I am starting to use hooks in React with ContextAPI.
This is the first example of my context with hooks:
import React, { createContext, useState } from 'react';
export const DepartureDateContext = createContext();
export const DepartureDateProvider = (props) => {
const [departureDate, setDepartureDate] = useState(new Date());
return (
<DepartureDateContext.Provider
value={[departureDate, setDepartureDate]}
>
{props.children}
</DepartureDateContext.Provider>
)
}
And this is second example:
import React, { createContext, useState } from 'react';
export const OriginContext = createContext();
export const OriginProvider = (props) => {
const [originText, originSearch] = useState('');
return (
<OriginContext.Provider
value={[originText, originSearch]}
>
{props.children}
</OriginContext.Provider>
)
}
When I use provider for those contexts, there gets the problem. Providers can stack and it starts to look ugly. Like this:
<OriginProvider>
<DepartureDateProvider>
<DestinationProvider>
<DestinationDateProvider>
<FlightSearch/>
</DestinationDateProvider>
</DestinationProvider>
</DepartureDateProvider>
</OriginProvider>
Since there is a possibility I will have more contexts, this will only starts to be even more uglier than this.
My question is, is there any way to make this prettier. Like for example merging all of those contexts into one single context? If so, how am I going to pass all states and their handlers, but to keep it clean and human readable?
Thank you.
Upvotes: 3
Views: 985
Reputation: 794
I have found one solution, but I am not sure if this is good for the use case I have or not. It will clear stacked contexts, but I don't know if this will provide more complexity in the future (depends on how many states I have in that merged context).
The idea is to transfer all states and their handlers into a single context and expose them together.
This is dummy example of what I am talking:
This is the context with multiple states:
import React, { createContext, useState } from 'react';
export const ContextSample = createContext();
export const ContextSampleProvider = (props) => {
const [state1, handler1] = useState('');
const [state2, handler2] = useState('');
return(
<ContextSample.Provider
value={[
[state1, handler1],
[state2, handler2]
]}
>
{props.children}
</ContextSample.Provider>
);
}
This is the App.js:
import React from 'react';
import { ContextSampleProvider } from './components/Contexts/ContextSample';
import Main from './components/Main/Main';
function App() {
return (
<ContextSampleProvider>
<Main/>
</ContextSampleProvider>
);
}
export default App;
And this is the Main component:
import React, { useContext, useEffect } from 'react';
import { ContextSample } from '../Contexts/ContextSample';
const Main = () => {
const [
[state1, handler1],
[state2, handler2]
] = useContext(ContextSample);
useEffect(() => {
handler1('Value1');
handler2('Value2');
})
return(
<div>
<div>
{state1}
</div>
<div>
{state2}
</div>
</div>
);
}
export default Main;
As you can see, I have removed nested contexts and it looks nicer.
But what I am worried about is this part:
const [
[state1, handler1],
[state2, handler2]
] = useContext(ContextSample);
It can potentially have more states and handlers which can become uneasy to read. But the big jump already is that I don't need to nest all contexts in the first place.
Any idea if this is a good approach and if there is maybe a better solution to this?
EDIT: I have made a post on my blog that talks about this problem. For anyone interested go to https://blog.ryukote.io/2019/08/15/react-hooks/ under section useContext.
Upvotes: 1