
I created the same app with React and Redux - sunilsandhu
https://medium.com/@sunilsandhu/i-created-the-exact-same-app-with-react-and-redux-here-are-the-differences-6d8d5fb98222
======
yawaramin
This article isn't really a comparison. It's almost completely dedicated to
explaining Redux. In fact the complexity of explaining even this simple app
with just a couple of components, should serve as a reminder of how complex
Redux is. The only real mention of the plain ReactJS version is near the end,
where it actually links to _another_ article which compares ReactJS and Vue.

~~~
a_wild_dandan
Redux isn't complex. It's a philosophy on how to manage state, and a few
simple concepts to realize that philosophy (store, reducer, action, ...). It
has nothing to do with React. Articles which effectively explain Redux by
wading through the minutiae of a boilerplate app are anathema to that goal.

If anyone reading this wants to learn Redux, just read the getting started
guide, or watch the co-creator's video series.[1] It's wonderful. If anyone
just wants a TL;DW, here's mine:

1\. The state of your application should be a tree. This tree is immutable. We
call it a store.

2\. Each branch of your state tree is generated by a pure function of the
previous state and an action. We call these reducers.

3\. The only way to effect change in your state is to dispatch actions.
Dispatching action X triggers the root reducer for action X (which triggers
the child reducers with action X, etc.), giving you the next state.

4\. Subscribe to store changes with listeners.

That's really it. A general roadmap for managing state in your software. Has
nothing to do with React. Or with user interfaces. Just a general approach to
software state. You can roll your own in a few minutes for your use-case. If
your use case _happens_ to be a React UI or C# app, then yeah, reach for
React-Redux or Redux.NET respectively.

But please, please don't learn Redux initially by looking at a React app that
uses React-Redux. That's hardcore jumping the gun.

[1] [https://egghead.io/lessons/react-redux-the-single-
immutable-...](https://egghead.io/lessons/react-redux-the-single-immutable-
state-tree)

~~~
ratww
Yes, Redux is easy. The problem is the incredible amount of boilerplate and
repeated code in most tutorials and beginner projects, in the form of actions,
switch statements and ALL_CAPS_STUFF.

That boilerplate can easily take 10x more lines than "real" code in reducers,
even in complex applications. Requiring three different files for each
reducer, as in the article presented, is completely overkill, and it only
makes sense when you're getting paid by the line of code.

However, there are great solutions to avoid that. I'll echo the recommendation
of createSlice:

[https://redux-starter-kit.js.org/api/createslice](https://redux-starter-
kit.js.org/api/createslice)

~~~
Izkata
> Requiring three different files for each reducer, as in the article
> presented, is completely overkill

He only has one [0]. Note that the parent directory is "redux", not "reducer"
\- the actions and actionTypes are separate from the reducers, because there
isn't a 1:1 relationship. This separation is because you could, for example,
have a second reducer that listens to the same Add action as the one in this
example - it doesn't need it's own action or actionType.

[0]
[https://miro.medium.com/max/1383/1*JsqDyA2Wy_08GnHS6SMDmw.pn...](https://miro.medium.com/max/1383/1*JsqDyA2Wy_08GnHS6SMDmw.png)

~~~
ratww
While you're technically correct, this is exactly what's overkill.

Actions and ActionTypes are pure noise.

And idk, having multiple reducers responding to the same action is a recipe
for trouble.

~~~
acemarke
I'll disagree with you on that last point. We specifically encourage that
pattern - treating actions as "events" that any part of the reducer logic can
respond to independently, rather than "setters".

Now, it's certainly true that _most_ actions will only be handled by a single
slice reducer, but having many slice reducers responding to the same action is
an incredibly useful pattern:

[https://redux.js.org/faq/actions#is-there-always-a-one-to-
on...](https://redux.js.org/faq/actions#is-there-always-a-one-to-one-mapping-
between-reducers-and-actions)

~~~
ratww
I do get the point of it being this way, but my problem with it is that it
feels too much like magic, I think I just prefer to have the 1:1 relationship,
like I already do with javascript functions or HTTP calls.

But even leaving that aside, I still think that this specific "feature" is not
worth the amount of boilerplate you need in most Redux apps, so it's not a
nice tradeoff IMO :(

I worked in some bigger apps, and before adopting ducks (and later a homebrew
version of createSlice) we had some bugs caused by multiple reducers firing.

I also think that it makes Flux/Redux a bit harder to explain

~~~
Tade0
You're not alone in this.

Redux isn't complex, it's _complicated_ \- needlessly so.

It takes just one look at its competitors to see this.

------
ericmcer
This app is way too simplistic to yield any benefit from state management.
This reads more like an intro to redux than a comparison of building apps with
vs without redux.

~~~
test1235
From the bottom of the article:

>But wait, where is the app that just used React? I thought this was a
comparison piece?

>This article is really a beginner’s guide to Redux to demonstrate how you
would go about adding Redux into an existing React app.

------
antoineMoPa
Every React + Redux I've worked with were needlessly bloated & slow. I think
that there is something that leads to bloat and slow performance in the
react+redux world, but I can't quite identify it yet.

~~~
gregkerzhner
I have had exactly the opposite experience. I recently rolled onto a React
project without Redux and the code was pretty gross. Multi hundred line React
components with markup, API calls, and business logic all mixed together in an
untested and untestable cocktail garnished with a heavy dose of prop drilling
and deeply nested callbacks.

Adding Redux to this app was a huge improvement. Test coverage is now almost
100%. The views are now tiny and simply render props and dispatch actions.
Complex workflows are handled beautifully by Redux sagas. Overall, the
codebase is now one of the cleanest I have ever worked on.

I am not saying you have to have Redux to have a good frontend codebase, but
it definetly helps a lot. If your app is even remotely complex, its hugley
helpful to have a global data store. If you are going to have workflows with
asynchronous components, Redux sagas are an incredible tool.

My hunch is that the apps that don't use Redux either 1. suck or 2. have had
some smart person hand roll a framework that has most of the core principles
of Redux in it. I am not that smart, and I don't want my codebase to suck, so
Redux is the best choice for me.

~~~
vevoe
Have you used redux-sagas on any projects before this one? How do you feel it
compares with redux-thunk?

I've used redux-thunk for all of my past projects but recently inherited a
project using sagas. It seems to be pretty unorganized and I'm wondering how
much effort I should put into cleaning it up, if it's even possible.

~~~
socceroos
I far prefer redux-sagas personally. I find the generator/yield style to
really reduce the mental overhead of a saga's flow as compared to a thunk.

~~~
Merad
Have you tried thunks using async/await? IMO its all the benefits of being
easy to read and understand without having to learn a totally new concept
(generators).

~~~
acemarke
Yep, agreed. The biggest missing capability there is being able to _respond_
to dispatched actions, which thunks can't do. But, most apps don't immediately
need to do that anyway.

------
dzonga
React and it's cousin in tow, Redux put food on my table. But like a famous HN
comment said: how many startups have been burn out due to the complexity of
wiring up those two powerful tools. I think frankly, when comparing frontend
frameworks the benchmarks should be 1. lines of code, since that determines
delivery 2. ease of maintenance as that enables easy to add new features 3.
how fast the app executes on the customers device. And frankly React + Redux
results in writing a lot of code

~~~
franciscop
I agree, but with CRA + JSX + React Hooks _usercode_ is a lot terser. I tried
React around 2014-2015 and hated it, now I really like it. Besides declarative
programming, styled components has been a life changer for the better.

I'm still torn with Redux though, seems great for big projects/teams, but
total overkill for small ones. I wrote a small alternative for my personal
projects
([https://github.com/franciscop/statux](https://github.com/franciscop/statux)),
what do you think about how it'd fare with your points? Looking for
improvements, and I saw a bug once (though I haven't been able to reproduce
and not 100% sure it was within the lib).

~~~
ericmcer
This is super true, React/Redux with hooks is really nice to work with. If you
use the redux hook it is super apparent what is coming from store, what is
coming from external props and what is internal state.

It makes it dead easy to cold read a components functionality and super simple
to detect code smells.

------
leshow
With the useReducer hook a lot of these differences have gone away. The
important difference is that redux will use global state. It's use of the
Context API makes components less portable.

Redux has it's place, I think it's structure can be nice at times, but you pay
for it. This app is not anywhere near the size where I would consider using
Redux though.

~~~
tracker1
I find where redux shines is when you move past the trivial app (which TODO
mvc style apps are). Especially if you're sharing various portions of state
between components at different levels and routes.

You have hooks for redux too, the following is at the top of pretty much all
my main components.

    
    
        import { useSelector } from 'react-redux';
        import useActions from './ComponentActions';
    

In my *Actions file, I export a wrapper for the actions individually, which
makes using actions pretty straight forward...

    
    
        import { bindActionCreators } from 'redux';
        import { useDispatch } from 'react-redux';
        import { useMemo } from 'react';
        ...
        export default deps => {
          const dispatch = useDispatch();
          return useMemo(
            () =>
              bindActionCreators(
                {
                  someAction,
                  anotherAction,
                  ...
                },
                dispatch
              ),
            deps ? [dispatch, ...deps] : [dispatch]
          );
        };
    

I also rely pretty heavily on redux-thunk, which lets me do simple workflows
for async...

    
    
        export const someAction = (input1, input2) => async (dispatch, getState) => {
          try {
            dispatch(someActionStart());
            const result = await api.area.someCall(input1, input2);
            dispatch(someActionComplete(getState(), result));
          } catch(error) {
            dispatch(someActionError(getState(), error);
          }
        }
    

I'd probably use saga if I ever needed anything much more complicated, which
is rarely the case.

In general, I tend to feel that following a few consistent patterns with Redux
tends to let you avoid a lot of problem cases dealing with state compared to
other options. Also, I tend to inject an intercept into my root reducer, this
way I can force dispatch a starting state for purposes of integrated browser
testing (gets deep-merged with current state).

    
    
        beforeEach(async () => {
          base = await page.evaluate(() => {
            // set store to a different initial state
            __STORE__.dispatch({ type: '__TEST_OVERRIDE__', payload: startingState });
            ...
            return __BASE__; // <-- injected configuration via server
          });
          ...

------
jaequery
I ask myself this a lot, are all the boiler plating you have to do for Redux
“really” necessary just to have state management?

Can we try combine the actions, types, and reducers into a single domain so
they aren’t seemingly repeated in 3-4 different locations. Maybe an option to
combine or separate as needed.

I know there are alternatives like Mobx and even the newer React Hooks so this
seem to affirm my thinking that it might not be all necessary.

And I personally haven’t seen any benefits from all the separations you do in
Redux at least from projects I’ve worked on, all it led to was verbosity and
more typing. It tend to make code more prone to mistakes and harder to follow.

If I see the benefits, I wouldn’t mind but either I don’t see it or haven’t
seen it yet. It just feels a bit like pre-mature optimization or over-
abstraction.

~~~
acemarke
It's definitely _not_ necessary, and that's exactly what our Redux Starter Kit
package can help with! See the `createSlice` function in particular:

[https://redux-starter-kit.js.org/api/createSlice](https://redux-starter-
kit.js.org/api/createSlice)

[https://redux-starter-kit.js.org/usage/usage-guide](https://redux-starter-
kit.js.org/usage/usage-guide)

~~~
jaequery
Thank you! I didn't know you guys were even attempting to tackle this problem.

Looking forward to seeing more improvements in this area.

------
Phillips126
A while back I was building a large application for an internal team at my
company. It got to the point where local state was just not solving all of my
problems so I started to explore Redux. I had been creating React apps for
several years but I could not wrap my head around Redux - it was far too much
complexity adding all sorts of actions, reducers, boilerplate, etc. I started
looking for alternatives and stumbled upon Mobx which I liked much better and
have been using ever since.

Mobx-react[0] felt like much less work with virtually the same outcome. You
create a single (or multiple stores), pass it into your app with a

    
    
        <Provider Store={store}>
            <App />
        </Provider>
    

and you are off to the races. When adding the global state to a component, it
was super easy:

    
    
        export default inject('Store')(observer(MyComponent))
    
        Or use decorators (requires ejecting create-react-app or modifying the webpack configuration settings):
    
        @inject('Store')
        @observer
        class MyComponent extends Component {...}
        export default MyComponent
    

Accessing the store:

    
    
        const {myValues} = this.props.Store
    

In the store you organize your code by observables (global variables), actions
(functions that modify observables) or computed (highly optimized functions
that return values derived from state). I treat it as a "source of truth" in a
single file.

    
    
        import {observable, action, computed, decorate} from "mobx"
    
        class Store {
            // Observables
            myValues = [0, 1, 2, 3, 4]
    
            // Actions
            addValue = num => myValues.push(num)
            
            // Computed
            get getTotal() {
                return myValues.reduce((total, cur) => total + cur)
            }
        }
    
        decorate(Store, {
            myValues: observable,
            addValue: action,
            getTotal: computed
        })
    
        const store = new Store()
        export default store
    

In the end I felt that my code was far more readable and maintainable but your
miles may vary.

Here is a relatively simple example of how to use mobx-react demonstrating an
observable, action, and computed:
[https://www.codementor.io/susanadelokiki/managing-state-
with...](https://www.codementor.io/susanadelokiki/managing-state-with-mobx-
iqax3wp63)

[0] [https://github.com/mobxjs/mobx-react](https://github.com/mobxjs/mobx-
react)

~~~
amoerie
I can attest to the genius that is MobX. Having worked on a frontend project
built with RxJs + React for nearly two years, I feel like I have kept all of
the benefits of reactivity and discarded a lot of complexity and learning
curve that mostly came from RxJs.

The API surface of MobX is a breeze, and it kind of pushes you into the pit of
success.

------
sysbin
I've been rewriting one of my hobby projects. I'm going from vanilla
javascript to react as a newbie in react. The project isn't even close to
being finished when I started the task of rewriting a month ago and the main
thing I've noticed is improvement in code structure.

I think someone would have a better time getting their head around the code
now and without me guiding them than before. Although the project was already
well organized. I make directory structure and naming conventions a high
priority/OCD obsession. I think thats mainly why my hobby projects never see
an end.

Unlike the author I haven't went with Redux and I've been just using react
context with hooks for passing data. I'm really pleased with react context
because now things are even more organized than without using context. The
only downside with react that I've encountered is trying for the least amount
of re-rendering when context changes. I've been reading a lot of optimizing
react blogs online. I'm trying to make the app realtime focused with
websockets and I don't want to face a difficult situation later on where many
users blows up the app to a crawl. Anyway I just wanted to express context is
really useful so far.

------
sod
If anyone here is familiar with the game factorio ... not using redux feels
like conveior belts vs redux being flying robots. Suddenly everything seems
easy and accessible. And writing spaghetti is nearly impossible.

If you ever intend to hire another person into a mature app using redux,
he/she is gonna love you for presenting all state via dev toolbar on a silver
platter.

~~~
kingartur44
+1 for the factorio reference

------
acemarke
Hi, folks. I'm a Redux maintainer. Wanted to let everyone know about the two
major things we're working on at this point.

First, we have a new official package called Redux Starter Kit [0], which is
our recommended toolset for writing Redux apps with less boilerplate. It
includes utilities to simplify several common Redux use cases, including store
setup, defining reducers, immutable update logic, and even creating entire
"slices" of state at once without writing _any_ action creators or action
types by hand.

RSK is useful for both folks who are new to Redux and experienced users, and
can be used day 1 in a new project or incrementally added to an existing
project. I'd strongly encourage anyone who's using Redux to try it out. In
particular, I'd suggest reading through the "Advanced Tutorial" page [1],
which demonstrates how to use RSK with TypeScript, thunks for async data
fetching, and our new React-Redux hooks API. You might also want to read
through the issue comment that lays out my "Vision for Redux Starter Kit" and
the problems it's meant to solve [2]

I just published RSK v0.8 this evening [3] which has a couple small breaking
changes (primarily renaming a `slice` field to `name` and making it required).
After that, I'm hoping to nail down a couple last bits of configuration, and
then push it to 1.0 within the next week or two.

After that, we're going to start working on a major revamp of the Redux core
docs. You can see my planned outline here [4]. The goals for the docs revamp
include:

\- Updating the tutorials, including removing outdated concepts like
references to "Flux", distracting mentions of terms or warnings that beginners
don't need to worry about, adding diagrams, and finding ways to improve the
explanations (like changing the "Middleware" page to explain how to _use_
middleware, rather than why they work this way). We will also add a tutorial
section that shows how to use Redux Starter Kit, and recommend that people use
it as the "default way to use Redux".

\- Adding a "Real World Usage" docs section. This would include topics like
choosing async middleware, debugging, folder structures, performance, and so
on.

\- Adding a "Style Guide" page. The Redux docs are deliberately unopinionated
about things like folder structures, async middleware, structuring actions and
reducers, and so on. However, we'd like to provide some official guidance on
our current recommended best practices. The Vue docs have a great page with
their recommendations, why they recommend certain patterns, and how strongly
they recommend them, and we'd like to do the same thing here. For example,
we'd recommend using a "feature folder" or "ducks" pattern for structuring
files, treating actions as "events" instead of "setters", and trying to put as
much logic as possible in reducers.

\- Adding a "Thinking in Redux" section. This would include concepts like
mentally modeling actions, the history of Redux and its inspirations, how it's
meant to be used, and why it works the way it does.

I'd love to have additional help from the community in working on this docs
revamp - I certainly can't do it all myself :)

Finally, I'd encourage folks to watch my Reactathon 2019 talk on "The State of
Redux" [5], where I talked about Redux's market share and how it compares to
other tools, as well as future directions for the library. In addition, my
post "Redux - Not Dead Yet!" [6] addresses some common questions about how
things like hooks and GraphQL relate to Redux.

If anyone's got questions, feel free to ask!

[0] [https://redux-starter-kit.js.org](https://redux-starter-kit.js.org)

[1] [https://redux-starter-kit.js.org/tutorials/advanced-
tutorial](https://redux-starter-kit.js.org/tutorials/advanced-tutorial)

[2] [https://github.com/reduxjs/redux-starter-
kit/issues/82#issue...](https://github.com/reduxjs/redux-starter-
kit/issues/82#issuecomment-456261368)

[3] [https://github.com/reduxjs/redux-starter-
kit/releases/tag/v0...](https://github.com/reduxjs/redux-starter-
kit/releases/tag/v0.8.0)

[4]
[https://github.com/reduxjs/redux/issues/3313#issuecomment-45...](https://github.com/reduxjs/redux/issues/3313#issuecomment-450601554)

[5] [https://blog.isquaredsoftware.com/2019/03/presentation-
state...](https://blog.isquaredsoftware.com/2019/03/presentation-state-of-
redux/)

[6] [https://blog.isquaredsoftware.com/2018/03/redux-not-dead-
yet...](https://blog.isquaredsoftware.com/2018/03/redux-not-dead-yet/)

------
wry_discontent
Redux isn't complex. It provides a simple way of doing state management.
React-redux is slightly more complex, but only because the docs give the
horrible advice of grouping things by type instead of domain. Using the
"ducks" pattern is vastly superior and simplifies a lot. It also hurts, I
think, that most people create actions and reducers that are 1:1. Those should
be different things.

Hooks, imo, simplified a lot of these issues.

~~~
acemarke
Yep, we're gonna change the tutorials and examples as part of the docs revamp
to emphasize "feature folders" and "ducks".

It's admittedly hard to come up with examples of actions that _aren't_ a 1:1
mapping in a small tutorial app, but maybe we can figure something out.

Related FAQ:

[https://redux.js.org/faq/actions#is-there-always-a-one-to-
on...](https://redux.js.org/faq/actions#is-there-always-a-one-to-one-mapping-
between-reducers-and-actions)

------
sebringj
Essentially redux is programming the state part of your app outside your UI
and having an immutable approach where given a state X with Y action, Z will
always result so its good for testing. This does allow you to reuse the redux
parts in different frameworks quite easily but I have never done that myself.
I personally find redux to be heavy for most apps as most apps are small but
in teams redux shines.

------
jdmg94
If you find Redux "Too complex" or you feel "it requires too much boilerplate"
then this is a clear indication you don't need Redux. The real use-case for
Redux is highly complex applications, if you're using redux for your todo app
then of course the cost/benefit ratio for you is not gonna work out

------
jcelerier
Thanks, I'll keep using QML ([https://github.com/jcelerier/TodoMVC-
QML](https://github.com/jcelerier/TodoMVC-QML)) ;p

