tl;dr: Rik does some learning about React contexts, then builds himself a (very) simple proof-of-concept thingy which may turn out to be the ‘right way’ to do this sort of stuff
React, Redux and all the props stuff
React is a way of building front end apps that has been intriguing me for a couple of years now. It’s one of those frameworks that entices me with its promises of Shiny while at the same time repulsing me with its sack-full of gotchas and huh-moments which can leave me feeling lost and stupid for days.
The biggest problem I’ve had with React is my usual do-it-yourself approach to learning the framework. I like to think that if I had the opportunity to work as part of a competent team of developers working on a big React/FluxOrRedux system then I’d tame this beast of a conundrum within a couple of weeks (are Facebook hiring? Asking for a friend).
I have built some stuff with React (side projects at work) and I do enjoy coding with the framework. Mixing HTML into my Javascript files doesn’t worry me - it used to be my approach to PHP before that language turned slick and professional on me. React states and passing props down chains of components can - at times - be a joy.
However my biggest problem with React has been state and props, particularly when dealing with values which get used in many, many React components scattered all over the build. Especially when those values - like user details - can be changed and updated by user actions in a component which I code up then somehow forget about.
Fluxing and Reduxing
It turns out that my problems are not down to me. Facebook developers themselves faced the problem of long prop chains and developed a solution to the mess even before they took the whole React thing public. Flux is a fascinating read, but I’ve never coded a single thing containing a Flux Dispatcher.
This is because Flux is hard. Facebook themselves admit that; they suggest using something else instead (because they are Coding Deities and I am not). The thing that gets suggested most often is Redux, specifically React-Redux. Just like Flux, Redux solves the problem of long props chains - it just does it in a different - allegedly simpler - way.
Strangely I’ve never coded a single thing containing a Redux reducer function. Redux always seemed like overkill for my little projects - until my little projects grew container chains that could stretch from England to France, by which time it was always too late.
Getting things into Context
React ships with something called ‘Context’ - a built-in solution to the long-props-chain problem. However the React engineers always recommended using solutions like Redux rather than Context. Context, they said, had ‘issues’. Like a good boy with no time, I followed the advice and wandered off to be flummoxed by Redux reducers instead.
This all changed earlier this year, when the React folks finally got around to fixing their Context’s issues. The warning banners that used to spatter the Context documentation have all disappeared. Context is our new saviour!
Well - sort of saviour. As the documentation makes clear, React Context solves the problem of lots of Components dotted all over the build needing access to the same small set of data: a locale string, for instance, or some site theme styles. But this is the sort of functionality I want. The experiments I’ve built tend to include users logging into a site and it’s that user data I need to share across my Components.
It was time for me to revisit the world of React to do me some learning!
Building a React App that uses Context
Rather than explain what I’ve done in reams of paragraphs, I’m just gonna throw the code into this blog post. I started with the usual create-react-app skeleton and tinkered. Have I mentioned how much I adore create-react-app? It is one of the most beautiful things I’ve ever encountered outside of nature. Thank you, Facebook engineers, for building and sharing create-react-app with me!
index.js
1 | // this is all entirely normal stuff for the index.js file |
My learning was certainly not all plain sailing. The official documentation is a bit hit-and-miss with its examples and Googling for solutions doesn’t bring up a heavy crop of results. What follows is what I think makes for a reasonable solution; it is certainly not the Last Word, and I’m looking forward to seeing how other coders solve the particular issues I encountered as I tinkered with my experiment.
My eventual solution for using a multi-attribute Context was to package the whole thing into its own ‘component’.
UserContext.js
1 | import React, { Component } from 'react'; |
The rest of the solution involves three normal, nested components.
App.js
1 | import React, { Component } from 'react'; |
SomeIntermediateReactComponent.js
1 | import React, { Component } from 'react'; |
All the fun stuff of consuming my context happens in the final Component.
HelloRik.js
1 | import React, { Component } from 'react'; |
So does it work?
It works for me!
Of course I am not a React expert. If people spot obvious flaws in my code then please don’t hesitate to let me know in the comments. Pointing out the Stupid Bits is how Rik learns best!