by Bill Girten
Clever React context tricks using Typescript — not Redux
TLDR; Leverage React’s Context API as a light and powerful alternative to Redux.
Let’s face it: when we first started to play with React, it was like a sugar rush. Just create a .jsx file, add a couple of dependencies, and Wham-O! — lightning-quick pages.
That’s when the excitement begins.
Next thing you know, you feel limitless as you engineer the presentation layer of your application at jet-speed. Then you get this crazy idea to make an AJAX call to some microservice and manage the state of the app.
That’s when the pain begins…
So you search Al Gore’s amazing Internet and find out the go-to solution to manage the app’s state is Dan Abramov’s Redux. Now you’re learning about Actions, Reducers and Stores and diving into ImmutableJS just so you can manage state. After you mapStateToProps, your React component is typically engaged in what is popularly termed “prop drilling”.
Initially, you’re okay with passing down properties from parent to child and, at times, to grandchild. However, as the application becomes more complex you notice that sometimes you are passing some properties through the component tree that are not used by a given descendant component.
Now what?!? You want to be able to manage the app’s state, but you want to do so without passing properties through the hierarchy. It’s time for some clever tricks.
How the React Context API helps
Facebook released the Context API in React v16.3 as a mechanism to pass the app’s assets through a Provider to any child component listening as a Consumer. This eliminates the “prop drilling” paradigm. Imagine: at any level, a parent component could define its own state (including methods) and provide them directly to any participating consumer. Additionally, you can set state by using the methods passed in by the Context’s Provider.
We’ll show you how to do this in the example below.
We begin by creating an “initial” State object which will be passed from the App component to the child components. Notice that this initialState also includes methods. This approach provides the capability of defining methods only once, so you can reuse them more easily.
Pass the initial State into the App component and provide a Context. Every component enclosed in the MyContext.Provider tag will have the capability of consuming the context (which in this case includes the initial state of the App component).
Bypass the “prop drilling” from the child component to grandchild component.
The local method handleFetchEvent provides the capability to execute the method passed by the context (in this case, updateStats). The component’s render method fires off due to this.setState.
On line 21, we consume the incoming Context.Provider, allowing us to access all those members and methods defined in the App component’s initial state.
Even though methods can be passed from higher levels of the DOM tree, we can also invoke re-rendering of the DOM by simply calling the setState method directly for a given React component.
And here we have the loaded application. Thanks for following along — you can find more awesome content from these authors at: