Context Free React Component

Requirement

Generally, when we start creating react components that are dependent on some common props we try to share these props through the react context API.

Another case is that if we want to prevent dipper props drilling then again we try to solve this issue with the help of React context API.

But in order to solve both of the above problems, we create new problems.

Problems

  1. Components that use context becomes tightly coupled code ( We have required parent dependency of provider context)
  2. Components are no more memoizable (Even we use React.memo it is not going to work if context value will be updated).

So how can we create a context-free react component?

Solution

As of now, we know how we use react context API to solve some problems and loses the re-usability of components because it depends on its parent context.

We should be having some kind of intermediator so that components should not depend directly on the context.

Now we will create an intermediator named MapContextToProps so as to make the context-free components.

 

const accumulatorMethod = (accumaulator, currentValue) => {
  const newAppend = subscribingProps.includes(currentValue)
   ? { [currentValue]: contextValue[currentValue] } : {};
  return { ...accumaulator, ...newAppend };
}

const MapContextToProps = ({
  dependentContext,
  Component,
  subscribingProps
}) => {

   const contextValue = useContext(dependentContext);
   const componentProps = Object.keys(contextValue)
                          .reduce(accumulatorMethod ,{});
   return <Component {...componentProps} />;

};
Let’s understand what we have implemented here. We have created a Wrapper/HOC that could be used as an intermediator for the context value. We can pass Component that is dependent on the context value and dependent context and third is the array of subscribing props( That we will be using in the component from the context ).
How To use it
const ContextValueDependentComponet = ({
subscribedProp1,
subscribedProp2
}) => {
  return <div>{subscribedProp1}</div>
}

<MapContextToProps
dependentContext={ContextObj}
Component={IndirectContextDependentComponent}
subscribingProps={["subscribedProp1", "subscribedProp2"]}
/>
Let’s understand what we have achieved here. First of all our component is now context-free react component. It is no longer directly depends on context instead we just need to pass props it can come from any source( from context, network, different storage, etc ).
See demo example here

Leave a comment

Your email address will not be published. Required fields are marked *