React with Redux? What about the 'context' issue?
Asked Answered
C

4

95

I normally post code related stuff on Stack, but this is more a question about what the general thoughts of the community are.

There seems to be a lot of people advocating the use Redux with React to manage data/state, but while reading and learning both I've come across something that doesn't quite look right.

Redux

At the bottom of this page: http://redux.js.org/docs/basics/UsageWithReact.html (Passing the Store) it recommends using the "Magic" of React 'Context'.

One option would be to pass it as a prop to every container component. However it gets tedious, as you have to wire store even through presentational components just because they happen to render a container deep in the component tree.

The option we recommend is to use a special React Redux component called to magically make the store available to all container components...

React

On the React Context page (https://facebook.github.io/react/docs/context.html) it has a warning at the top:

Context is an advanced and experimental feature. The API is likely to change in future releases.

Then at the bottom:

Just as global variables are best avoided when writing clear code, you should avoid using context in most cases...

Do not use context to pass your model data through components. Threading your data through the tree explicitly is much easier to understand...

So...

Redux recommends using the React 'Context' feature rather than passing the store along down to each component via 'props'. While React recommends the opposite.

Also, it seems that Dan Abramov (the creator of Redux) now works for Facebook (the creator of React), just to confuse me more.

  • Am I reading all this right..?
  • What is the general current consensus on this issue..?
Carpenter answered 5/4, 2016 at 13:51 Comment(1)
Ahh this is a great question, I'm very curious to hear the viewpoints of others as well! I'm slightly afraid it'll get closed due to the discussion aspect. I really hope it doesn't.Andreasandree
I
95

Context is an advanced feature and is subject to change. In some cases its conveniences outweigh its downsides so some libraries like React Redux and React Router choose to rely on it despite the experimental nature.

The important part here is the word libraries. If context changes its behavior, we as library authors will need to adjust. However, as long as the library doesn’t ask you to directly use the context API, you as the user shouldn’t have to worry about changes to it.

React Redux uses context internally but it doesn’t expose this fact in the public API. So you should feel much safer using context via React Redux than directly because if it changes, the burden of updating the code will be on React Redux and not you.

Ultimately React Redux still supports always passing store as a prop so if you want to completely avoid context, you have that choice. However I would say this is impractical.

TLDR: Avoid using context directly unless you really know what you are doing. Using a library that happens to rely on context internally is relatively safe.

Isocracy answered 5/4, 2016 at 16:5 Comment(6)
Well said Dan. The risk is, if React removes context altogether in a future release it would likely require rework to update any existing Redux app. Redux would be unlikely to be able to shield users from such a change. Given that you're now with Facebook, the good news is that I expect you'll have plenty of advance notice if context ever goes away.Charliecharline
React won’t remove context. I mean, it’s technically possible, but the whole reason it exists is because numerous products inside FB needed it. So unless there is an equivalent solution, it won’t go away. But its exact API may change which is what we shield users from.Isocracy
Another important note is React plans to use context more rather than less in the future. We think it might prove useful for styling, animations, gesture handling, etc.Isocracy
It's interesting to note however, when you get libraries of React Components (e.g. Material-ui), then they naturally will not form part of your application state model, but are still a tree of React components just the same, with the same requirements of maintaining their own state model and data flow separate to the 'main' application. So they are making use of the context feature as the only means (to them) of passing data down to their child hiearchy.Worry
@Worry Generally the recommendation is that third party components are “controlled” so they accept props that you manage in your state.\Isocracy
@DanAbramov what about new context API? Is it still not recommended to use?Louvre
A
5

I don't know about others, but I prefer using react-redux's connect decorator to wrap my components so that only the props from the store I need are passed into my component. This justifies the use of context in a sense because I am not consuming it (and I know, as a rule, any code that I am in charge of will not consume it).

When I test my components, I test the non-wrapped component. Because react-redux only passed the props I needed on that component, I now know exactly what props I need when I'm writing the tests.

I suppose the point is, I don't ever see the word context in my code, I don't consume it, so to a certain degree, it doesn't affect me! This doesn't say anything about Facebook's "experimental" warning.. If context disappeared, I'd be just as screwed as everyone else until Redux was updated.

Andreasandree answered 5/4, 2016 at 15:7 Comment(3)
Interesting... I see what you mean about 'react-redux' using Provider and connect to abstract away all the Context stuff. I guess with Dan Abramov now being at FB you'd hope that if Context changed Redux and 'react-redux' would be updated... But no guarantees though, and FB's "experimental" warning is still there for all to see.Carpenter
I certainly have hope that if FB doesn't keep react-redux in the loop in case anything does happen to context, an open-source contributor somewhere more familiar with redux than me will; if not, I'll figure it out and do it myself!Andreasandree
I asked Dan for his thoughts via Twitter... Nice answer, along the same lines... Use the library that uses Context, don't use it directly.Carpenter
C
1

There's an npm module that makes it really easy to add redux to the react context

https://github.com/jamrizzi/redux-context-provider

https://www.npmjs.com/package/redux-context-provider

import React, { Component } from 'react';
import ReduxContextProvider from 'redux-context-provider';
import createStore from './createStore';
import actions from './actions';
import Routes from './routes';

export default class App extends Component {
  render() {
    return (
      <ReduxContextProvider store={store} actions={actions}>
        <Routes />
      </ReduxContextProvider>
    );
  }
}
Conglomerate answered 12/2, 2018 at 19:14 Comment(0)
N
1

React ships with all the features you need to handle your state without a single additional library. Most of your application's states should not be global as they live just fine in a useState or useReducer or custom hook next to your components.

So before you dive into the world of advanced state management (e.g. Redux), consider using the tools React ships with out of the box.

If you are interested in learning a bit more about this, I'd recommend this article by Andy Fernandez, which dives into the details on Redux: Context API vs Redux

Natant answered 29/11, 2022 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.