Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it sane to use React `context` to access model mutators in a Flux-less app?

I'm starting a new React app and, seeing all the news in the ecosystem, I want to go slow and actually consider my choices, starting with just React/Webpack/Babel, and introducing more.

The first of these choices is whether to use Flux or not (more precisely, Redux, which looks great and seems to have won the flux wars). Here is where I am:

  1. I understand Redux's benefits, summarized on SO by Dan Abramov. They look great, but I'd rather introduce things one step at a time.
  2. In plain React, parent→child communication is done with props, and child→parent communication happens with callbacks. See Doc / Communicate Between Components, or SO / Child to parent communication in React (JSX) without flux, or this codeacademy Redux tutorial which starts out by saying "no need for Redux if you're fine with plain React and all your data in a root component".
    • Which looks just fine for my purpose...
    • ... however, the sad part is that these callbacks have to be passed down the component chain, which becomes quickly tedious as the levels of nesting grow.

To solve this without introducing new dependencies, I found two articles (1: Andrew Farmer, 2: Hao Chuan) encouraging usage of the recently-introduced context feature of React.

→ Using context would let me expose my model-mutating callbacks to my child components. To me it doesn't sound like a horrible misuse: I wouldn't be passing model data, just references to functions for binding on event handlers.

  • Does it sound sane?
  • Any other plain-React suggestion for convenient child→parent communication?

Thanks.

like image 658
Ronan Jouchet Avatar asked Oct 29 '22 22:10

Ronan Jouchet


1 Answers

Answering my own question after watching Dan Abramov's Getting Started with Redux series, which I warmly recommend.

Yes it looks like it's sane: Redux faced the very same problem and solved it with Context (at least initially, the implementation may have changed). It is implemented and packaged (among other things) in the react-redux bindings under the <Provider> component and the connect() function.

  1. Initially, at the start of step 24 - Passing the Store Down Explicitly via Props , we have a Todo app with a Redux store available as top-level variable. This sucks (for 1. testability/mockability, 2. server rendering needing "a different store instance for every request because different requests have different data"), so the store is demoted from top-level variable to a root component prop.

  2. As in my case, having to pass the store as prop to each component is annoying, so in 25 - Passing the Store Down Implicitly via Context, Dan demonstrates using Context to pass the Redux store to arbitrarily nested components.

  3. It is followed by 26 - Passing the Store Down with <Provider> from react-redux, explaining how this was encapsulated in the react-redux bindings.

  4. And 27 - Generating Containers with connect() from React Redux further encapsulates generation of a container component from a presentational component.

like image 94
Ronan Jouchet Avatar answered Nov 09 '22 12:11

Ronan Jouchet