DEV Community

Itay Schechner
Itay Schechner

Posted on

Using the React Context API, the right way (a time saver)

Hey everyone! I'm Itay, a fullstack web developer who specializes in back-of-the-frontend code, particularly with React.js. Today, I'll teach you useful code hacks to supercharge your codebase.

What you'll learn

  • The flaws of the context API
  • The logical wrapper factory
  • The action factory

Before We Begin

I want to introduce my common way of writing context providers, so that I can write custom components and hooks and the you‘ll understand their meaning without me having to explain too much. If you want me to do a more simple context tutorial in the future, let me know in the comments.

My Context Naming Convension

The Flaws of the context API

The Context API is the state-of-the-art way to manage state in React. It is an alternative to Redux, MobX, and a large variety of state management libraries made by the community.

Repetitive Tasks

Almost every time I use the Context API in a frontend application, I run into doing the exact same thing: I create an AuthContext, like the one below:
Auth Context Provider

Then, I use the signed in state anywhere in my app:
Usage

Imagine having 60 auth-protected component in your app. Your codebase would be a mess!

What are the problems with this approach?

  • Messy code
  • Repeating a lot of code all the time

Easy to mess up your codebase

Suppose you have a context and a ContextProvider component attached to it.

In the same component you provided the context, you want to use the context for a button, like the example below:

Component A Provides and Consumes!

You wanted to do something really simple, but ended up messing up your codebase. As a workaround, you might do something like this:

A Workaround

But now, we are back in the repetitive tasks zone.

Component Factories to the rescue

A component factory is a function that returns a React functional component.
I. e: () => () => <div></div>

We can use component factories to clean up our codebase and create a clean code structure. Today, I will teach you about 2 time-saving and life-saving factories: The context logical wrapper and the context action factory.

Logical Wrappers

Logical Wrappers solve the problems of conditional rendering we saw in the beginning, without having to mess up your codebase. You create them with this function:

Logical Wrappers

Then, our problem from before can be solved in just a few lines of code:

Using Conditional Wrappers

You can save tons of time by using this component factory for every context you create.

Context actions

Context actions are high-reusable components because of the way they are built.

Create Context Action

Now, we can create out ComponentB with just one line of code!

Using Actions

Now you must ask yourselves - why would you add the className prop to your context action? The reason is simple: Reusability. The best way to demonstrate it is by example:

Reusability

Wrapping up

Do you want to see how to add icons to our action buttons? How to use TypeScript with those? Let me know in the comments below.

In the next episode, we'll discuss supercharging forms with react! Give me a follow if you want to see this.

See component factories in action (at branch 1.1.2):

GitHub logo itays123 / partydeck

A cool online card game!

Discussion (31)

Collapse
ncpa0cpl profile image
ncpa0cpl • Edited

Overall good article, but I have a big problem with this statement:

The Context API is the state-of-the-art way to manage state in React. It is an alternative to Redux, MobX, and a large variety of state management libraries made by the community.

No, Context API is not an alternative to Redux or MobX, Context API is not a state management tool, it has absolutely nothing to do with managing state.

Context API and state management libraries are supposed to solve two completely different problems.

State management library is intended to, well, manage state, so set the state, read the state and update the state.

Context API is intended to share a piece of data across many React components without prop-drilling. (Context does not "manage" anything)

Collapse
hyggedev profile image
Chris Hansen

Hey great article D: So just to clarify, Context is not for state management, as you can handle state anyway you like, but the ContextProvider allows you to have access to that data anywhere without prop drilling? Is my mind in the right place? I know how to use it, I just hope I know WHY I'm using it LOL. Thanks ahead.

Collapse
ncpa0cpl profile image
ncpa0cpl

You are correct, except Context Provider does not allow to have access to that data anywhere. It's only within React Components that are descendants of that Provider.

What's most important Context does not give any option to access it's data outside the React tree (Redux and other State Management library do)

Thread Thread
hyggedev profile image
Chris Hansen

Ahh okay gotcha. Perfectly said, I get it now. Thanks! 👌

Collapse
itays123 profile image
Itay Schechner Author

You are absolutely right. Hooks are responsible for the state management in those examples.

Collapse
Sloan, the sloth mascot
Comment deleted
itays123 profile image
Itay Schechner Author

Not only useState. You have the useEffect hook, an essential hook for every context & hooks back-of-the-frontend code, the useMemo and useCallback hook that I highly recommend you to understand, and a lot more you can do with those.

Thread Thread
youyirhode profile image
YouYi

You are right. I took a deep look of hooks.Basically, I noticed React separate the whole html, css structure from data. Then we can store data ,change data, update data, share data. That is state management, and all hooks serve for that.

Collapse
radist2s profile image
Alex Batalov

You absolutely wrong, thanks God we have RFC to mange context state changes github.com/facebook/react/pull/20646
Wait for a while to have ability to remove any state managers from your React app.

Collapse
ncpa0cpl profile image
ncpa0cpl

It's a pull request for an experimental feature therefore it's not really relevant to this discussion.

And even if this was already available in the stable version it doe not make Context a state management tool since it lacks the ability to do anything with the state it distributes.

To make things clear, Context API consists of(as of right now):

  • createContext method
  • useContext hook

And those provide you with a Context Provider, Context Consumer and the Context value.

None of the above allows for managing the state, there is nothing that would allow for updating state or adding side effects.

Thread Thread
radist2s profile image
Alex Batalov

This feature definitely will be added in stable version. Second argument as comparator will allow you to check is the target value in context is really changed. Isn't it the state manager behavior?

Collapse
tanzimibthesam profile image
Tanzim Ibthesam

Well in React documentation its written React Hooks has been created to manage state and prevent from using 3rd party libraries like Redux

Collapse
httpjunkie profile image
Eric Bishard

Good article and I'm not going to get upset about the comment about it being an alternative for MobX and redux because I understood what you were saying you definitely have the ability to avoid those tools by simply using context and a lot of the times context API is used specifically for state management so I can read between the lines and I think you have some good examples in here too with the logical stuff again great article

Collapse
moisesrj97 profile image
Moisés Rodríguez

A bit off topic, but I've been searching how you make those pretty code images and I can't find it hahaha.

Collapse
metammodern profile image
Bunyamin Shabanov

There are extensions for vscode, like PolaCode and others.

Collapse
transli profile image
transli

You can use carbon.now.sh/

Collapse
stephensamra profile image
Stephen Samra

Here you go: carbon.now.sh/

Collapse
khoan profile image
khoan • Edited

wow, first time I come across this expression: <>{ condition ? children : null }. What's its name? Thanks.

Collapse
itays123 profile image
Itay Schechner Author

Ternaty operator
When you put it inside a React fragment, you ensure that the function will always return JSX.

Collapse
khoan profile image
khoan

ah, I think, it should be: <>{ condition ? children : null }</>

Or, the closing </> is optional? Thanks.

Thread Thread
itays123 profile image
Itay Schechner Author

Yeah, you should close it. I'd review my code snippets again next time.

Collapse
coderreviewio profile image
Mustafa Alroomi • Edited

CreateAction takes 3 args, first one is label not context

Collapse
itays123 profile image
Itay Schechner Author

Oops:) forgot to insert that... Thanks for the feedback!

Collapse
panoscool_ profile image
Panos K.

Amazing article. Looking forward for typescript, icons and forms.

Collapse
payapula profile image
payapula

Nice article. Learnt about a new pattern with respect to Contexts. Thanks for sharing! 🏅

Collapse
tommoran profile image
Thomas Moran • Edited

Wouldn't you still need to do a conditional render to show the Auth vs NotAuth components as shown in your third snippet?

Or would you plan on returning both and letting Context worry about which to show

Collapse
itays123 profile image
Itay Schechner Author

My solution is

<Authenticated>You're signed in</Authenticated>
<NotAuthenticated>
Oops, go sign in
</NotAuthenticated>
Enter fullscreen mode Exit fullscreen mode

The reason I like it so much is that you can use one without the other, like the example in the logout button.

Collapse
subaleethedev profile image
Dustin Subalee

How exactly is the Component Factory pattern you mentioned (coined?) different to HOC (Higher order component)?

Collapse
itays123 profile image
Itay Schechner Author

It's different because of the simplicity. The warpper won't need a higher order component, you just create it with one line of code.

Collapse
femiobadimu profile image
Femi Obadimu

Nice nice..
An alternative to redux
..

Collapse
ryannerd profile image
Ryan Jentzsch

For state management I recommend ReactN. Easier to use than Redux, lightweight, with all the features of Redux. github.com/CharlesStover/reactn