
Things to learn in React before using Redux - callumlocke
https://www.robinwieruch.de/learn-react-before-using-redux/
======
k__
My first project with React was a mess, mostly because of Redux. Not because
it's bad, but because the lead dev was adamant about using something Flux
like. First we had Flummox, than he rewrote everything in a week with Redux,
that was 2 years ago, before Redux had sane async helpers.

In my current project (where I'm the lead, haha) I'm trying to got state/props
all the way.

I think for most apps it's more than enough AND it's easier to get started for
new devs.

React is really easy. I mean coming from Ember and ExtJS, its API is a walk in
the park and you can get really far without extra state management.

One thing that is important for this approach, minimize nesting.

You don't want to pass down everything from the app, to the screen, to the
list, to the item. etc.

Instead of doing:

    
    
        <List items={items} />
    

do it like that

    
    
        <List>
          {items.map(i => <Item item={i}/>)}
        </List>
    

No nesting of screens (top-level components), no (hidden) nesting of
components. This may seem kinda strange, because the first example has no
dependency to the Item component, but it gives the component that uses the
List direct access, which simplifies props-passing immensely.

This doesn't work for all apps, but it's a good starting point.

I ended up with 2 folders, screens and components, that are both simply flat
lists of component files.

~~~
Androider
Also, when you do use Redux, as in your nesting example don't pass props
through components that don't have any need for them except they propagate the
prop to someone else. It's absolutely fine to connect() a component deeper in
the hierarchy. Passing everything down is an anti-pattern with Redux,
separation of concerns still applies and the props of a component defines the
API, don't clutter that API with unrelated things.

Components only receiving props that they themselves need has kept things
clean in our massive codebase, and allows you to effortlessly move things
about and easily re-use components wherever it makes sense.

~~~
prance
I don't agree with the view that a component doesn't need a prop "itself" if
it "only" passes it on to a child component. That child component is a part of
the parent. If one decided that e.g. the child is too simple to warrant to be
its own component and inlined its render() content in the parent instead,
suddenly its used props would be needed by the parent "itself".

Another thing to consider is that one tightly couples components to stores
when connecting. So reusability of these components is hampered.

~~~
pedalpete
If was my understanding that if a component has a prop which changes, even if
that prop is passed down the tree, the component will still update.

This is one way I use redux, the connector watches for changes in state and
then updates the component directly, rather than passing props down the tree.

------
spinlock
I'd rather use Redux without React than React without Redux. Sure there's some
boilerplate but we use typescript so the redux boilerplate seems trivial in
comparison.

Redux keeps your app _simple_. That's not the same as easy. It means that you
can reason about your app as it grows and new features are added. When you run
into problems like: this page is taking too long to load because we do
calculations x, y and z on the server to push the data to the app. But z takes
forever to compute and makes the initial page load painful. With Redux, you
can move z to an async endpoint and just load x and y on page load (put the
component that needs z in a loading state). Then, fire an ajax request when
the component mounts to get z. When that call returns, it updates your store
and the component that needs z transitions from loading to loaded.

I took me a couple of hours to do the above in a Redux app and decrease the
page load from 2 seconds to 300ms. And it didn't add complexity to the app
that would make it difficult to maintain. I don't even want to think how long
that refactor would take if the state had been managed with React.

And ... don't even get me started on how easy -- and fast -- it is to test a
Redux app. Zero side-effects means zero setup and teardown between specs.

------
sghiassy
The rush to use Redux for every React project is one of the most annoying
parts of the React community; using a tool just to use it, before
understanding if you need it or not. This article summarizes a lot of good
points.

~~~
nfriedly
Agreed. Until recently, my team was responsible for most of the official IBM
Watson service demos, and we standardized on React for those and built up a
nice library of react components[1]. None of them used Redux, though, because
in general it just wasn't needed.

When we handed off responsibility of these demos to the individual service
teams, we wrote up guidelines that specifically recommended React but not
Redux - with the logic that if the demo is getting to a point where Redux is
providing value, then it's probably too complex for a demo.

Our new project is a more involved web app that includes lots of state, shared
across many different components, and we're making great use of Redux there.

[1]: [https://watson-developer-cloud.github.io/react-
components/](https://watson-developer-cloud.github.io/react-components/)

~~~
maaaats
One of the things I find hardest with redux is to make reusable components
(across projects), as they have to be added to the state tree somewhere, and
then connected. With nested components you may get implicit dependencies on
where in the tree it should be. All this makes it very cumbersome.

So even though most of our apps use Redux, the reusable parts use setState as
they then can be completely independent.

~~~
acemarke
Yeah, that is a tradeoff - globalized state makes a lot of scenarios easier,
but does make complete encapsulation and reusability harder.

Most of the third-party "Redux-connected component" libs I've seen provide a
reducer that they expect to be added to the root of the state tree under a
specific key name. Works, but it's not ideal. I've seen a few that let you
provide a selector or key name when you initialize the library, so that the
library is more flexible in how it's connected.

There's been a lot of discussion of various approaches for implementing fully
encapsulated/reusable Redux-based React components in Sebastian Lorber's
"Scalable Frontend with Elm or Redux" repo [0], and my links list has a
section of additional articles on the topic of encapsulation with Redux [1].
My Redux addons catalog also has a large section for libraries that implement
some form of per-component state or component encapsulation in Redux as well
[2].

So, it's not impossible, but it does take work and there are tradeoffs either
way.

[0] [https://github.com/slorber/scalable-frontend-with-elm-or-
red...](https://github.com/slorber/scalable-frontend-with-elm-or-redux)

[1] [https://github.com/markerikson/react-redux-
links/blob/master...](https://github.com/markerikson/react-redux-
links/blob/master/redux-architecture.md#encapsulation-and-reusability)

[2] [https://github.com/markerikson/redux-ecosystem-
links/blob/ma...](https://github.com/markerikson/redux-ecosystem-
links/blob/master/component-state.md)

------
acemarke
As usual, this is an excellent article by Robin. Well-written, and full of
great information.

It's worth noting that both the React and Redux teams (including Dan Abramov
and myself) agree that you should focus on learning React first, and _then_
learn Redux. That way there's fewer new concepts and terms to learn at once,
and once you understand React, you'll have a better appreciation for what
kinds of problems Redux can help solve. That's not to say you _can't_ learn
them both at once, just that it's the suggested approach that will work best
for most people.

------
hippich
As a general rule do not use `this.react` inside `setState({ ... })` - this
will cause you problems eventually due state updates being async.

If you need to use state to set new state, use functional callback instead -
[https://facebook.github.io/react/docs/react-
component.html#s...](https://facebook.github.io/react/docs/react-
component.html#setstate)

------
tchaffee
Worth a read. It summarizes in one place much of what I learned bit by bit
from various other articles.

------
captainmuon
I wish React would come with a standard way to handle Ajax (or a convention or
semi-standard library would emerge). _(Edit: "comes along" in the sense that
immutability-helpers, redux and create-react-app come along with react. I'm
not proposing to add anything to the react module. I'm not the world's best
expert on react, but before downvoting can you please assume I know a little
bit of what I'm talking about?)_

Something that:

\- Can fetch JSON according to criteria from an API

\- Caches stuff locally (just in memory, or in local storage) in case of
duplicate calls

\- Deals with multiple concurrent calls, and merge them (e.g. fetching 1 and
then 2,3,4 before 1 finishes -> either cancel 1, or wait until it finishes,
and then fetch only the last requested item.

\- And all the stuff I can't think about right now, like cancellation and
timeouts

Plug your pure component into one of these, tell it about your API, and you're
done. It's really error prone to write these containers yourself. And I think
Redux doesn't really help much with Ajax.

~~~
fokinsean
This is one thing I miss about Ember. We recently moved to React and I'm
really starting to miss Ember Data (even though it can be very picky).

~~~
spicyj
I haven't used Ember Data much. I'd be curious how you think it could apply or
could be ported to React. Maybe you'd have time to write up a short gist of
what you wish you could write in React?

------
noncoml
IMHO Redux is a heavy, clunky and awkward practice that is only holding React
back.

My advice to anyone reading this forum is give MobX a try before deciding to
commit to Redux.

~~~
ng12
Don't kid yourself, MobX comes with it's own baggage. Both are great
libraries, both have advantages, both have drawbacks.

~~~
tomduncalf
What are the downsides of MobX that you've come across? The main ones I've
encountered are not being sure why something isn't reacting (always my fault
but not always that easy to track down), odd interop issues with observables
actually being "proxy" objects (e.g. useless console.log unless you call
toJS), I guess no middleware-type concept or Saga type side effect management
(never really used middleware in Redux and disliked all the ceremony around
side effects)... that's all I can think of right now but curious to know
others experiences.

I honestly can't imagine any reason I'd go back to Redux aside from if it was
used on a project I was working on though. I can develop so much faster and
with fewer bugs (as typechecking MobX code thoroughly is much easier than
Redux with Typescript) that there's no comparison, and like the OP, I think
everyone should try it out - you'll almost definitely be pleasantly surprised!

~~~
aidos
I've been working with it recently. The lack of prescriptiveness is an issue
generally. No different from not having a library, but it's worth considering.

The library itself works really well. Use strict mode and everything is super
fast and reliable.

Today we've been evaluating mobx-state-tree. It has some noise (not as bad as
redux). It's opinionated which helps to remove architecture decisions. So far
it looks promising.

~~~
ng12
I think this is why the MobX fanboyism irks me so much. It's a great little
library but it does not solve the problems I have. I want to enforce the
smart/dumb paradigm, I want to be able to quickly grok app state and monitor
updates, I want nice dev tools, I want the data to be separated from
components to the highest degree possible, I want to persist/restore complex
app state. All of these are fundamental talking points for Redux and largely
unnacounted for by MobX.

If all you switched to MobX just to avoid the boilerplate you didn't need
Redux in the first place.

~~~
aidos
Well, the main reason for using these libraries is to automatically drive
react. You want it to be easy to change your state and have that mirrored in
the interface.

Mobx helps with much of what you've asked for above. Mobx-state-tree will give
you even more from that list. Personally I think the persist/restore goal (and
time travelling) is overrated (though mobx-state-tree will give you those).

~~~
ng12
It does not give you more from that list. MobX is, by design, non-prescriptive
about who's touching your stores, how they're being passed around, how they're
being updated, or how the API of your store looks. It's all fine if you have
one or two developers but is a dangerous thing for large teams.

Have you used Redux's devtools? I wouldn't give those up for anything. Not
sure if MobX has anything comparable.

~~~
aidos
I have used them, yeah. Mobx-state-tree (MST) can be wired directly to the
redux dectools.

The strict mode in mobx ensures that stores can only be updated via actions,
so you can restrict updates from that point of view.

On the flip side - mobx makes it dead easy to minimise your core state and
transform it efficiently (and declaratively) for use in the front end (or
wherever). I'm told reselect helps that use case now, but you'd be hard
pressed to do a better job than mobx in that regard.

Personally, I found that my code was too obscure with redux. In implementing
our login flow (it has more paths than most), I found that it was hard to see
the real code between the architecture.

As ever, it's important to evaluate these tools critically to see where the
fall down (which is what I've been doing with MST today). Too often people
evangelise their product of choice while hiding the areas in which it's weak.

And to play devils advocate, redux will have you push a lot of code into
middleware where people are left to do all sorts of crazy - it's not all the
rosy enlightened path :-)

One of the things that pulled me to MST was that I couldn't see a simple way
of managing cross-cutting concerns with my mobx architecture. MST (and redux)
make that dead simple.

------
bernadus_edwin
People should learn eventEmitter or PubSub before learn redux

~~~
RussianCow
Why?

~~~
bernadus_edwin
Redux is too complex and too many line of code. Most of activity why need
redux are async fetch and eventEmitter notification. My advice is try
eventEmitter first. If u need more, than jump to redux or mobx. The main
reason use redux is if u need time travel

------
TotallyHuman
I don't understand why anyone would use React at all with the ridiculous
license.

~~~
enraged_camel
Well, there are many reasons to use React (the large ecosystem means you can
find libraries and tutorials easily, for example) but yes, the license is a
deal breaker for many, especially larger companies with legal teams who
actually understand the ramifications.

~~~
YCode
Microsoft has no problem using React -- what are the ramifications?

~~~
travmatt
Doesn't Netflix as well?

~~~
altotrees
Yep, and Palantir also. I wish my company would be more open to using it, but
the patent issue makes it a non-starter for us.

