When I first got introduced to context API in react, I was overwhelmed. Having learned to work with redux since my early days with react, I've never had the need to avoid or use prop drilling. I've always felt redux being one of an integral part of react. Even today, if you talk about react to anyone with no proper knowledge of react, they would somehow know that redux exists in react ecosystem; they don't know about any other state management libraries but they would definitely know the word "redux".
It's been nearly a year, I've been away from redux. I've never actually had the need to use redux or any global state management, it's probably because having used react-query most of the data that needs to be available globally are already managed and I've learned to organized the states and components so that I would need lesser props to be drilled. I have to say, there've been instances where I've realized that using some sort of state management would be of greater benefit, and for those, I (regrettably) chose to use the context API.
As a react developer, when you've reached a certain level of maturity you will be familiar with using context API pretty easily. I mean what's so difficult about that, right. You create a provider, pass the value which will be consumed by a consumer using useContext hook anywhere within the components wrapped by the provider. But one of the crucial part that most of the developers I've interacted with have failed to recognize is that all the components that subscribe to the value provided by the consumer will re-render if any states within the context API is updated. I've even found developers showing off their advanced knowledge by using context almost everywhere where simple props would have worked.
Just today, I was reviewing a code of my fellow developer. There was an Order component that had a CustomerDetails component as its child. I don't know what triggered him to use context API but all the data of the CustomerDetails which was basically a form was pulled from the context and to top it up the context provider was used at the main entry file of the project.
Just to give an overview of how the code was written:
The code for context API
export const ContextWrapper = React.createContext<IContextWrapper | null>(null);
function ContextProvider({children}:IContextProps){
const [customer,setCustomer] = useState();
return <ContextWrapper.Provider value={{customer,setCustomer}}>{children}</ContextWrapper.Provider>
}
The code for CustomerDetails
function CustomerDetails(){
const context = useContext(ContextWrapper);
return (
<div>
<input name="fullName" onChange={(e)=>{
if(context){
context.setCustomer({...context.customer,[e.target.name]:e.target.value})
}
}}/>
</div>
)
There was no need for context here and it could be simply avoided by using the customer state directly within the CustomerDetails.
I think context API shouldn't be used even for smaller components. I always try to look for ways to prevent re-renders if I use context API probably by just using it for injecting some data which are never updated once created like globally providing theme variables or login states. I always suggest mastering the concept of states first because it might seem easier to work with state at the beginning but throughout your career as a react developer you will always be working on managing states and believe me I've seen states being misused a lot even by senior developers.
Once you've understood states then move on to understand the consequences of context because apparently most of the developers are used to the benefits of context API without understanding the performance impacts it has on your project. Never try to use context, always try to manage the states within the component, try to restrict props, try to localize your states, and understand which component should be the owner of a given state. I would always prefer some state management libraries than using context API and always suggest thinking of context API, not as an advanced react concept but as an easier workaround for avoiding prop drilling with performance hits.