DEV Community

You don't have to use Redux

Anssam Ghezala on June 01, 2019

A React application is basically a tree of components that communicate data with each other. Passing data between components is often painless. H...
Collapse
 
javaguirre profile image
Javier Aguirre • Edited

Nice comparison! :-D

IMHO the key to make an application easier to maintain is testing. Many people forget about this but in the end needing more/less lines of code is not as important as having the best possible testing environment.

That's why we used redux and saga, it makes the application very easy to test if you follow its rules.

Collapse
 
seif_ghezala profile image
Seif Ghezala ๐Ÿ‡ฉ๐Ÿ‡ฟ

I'm very curious about how Redux provides a better testing environment. I feel like React evolved enough so that you can achieve anything you do with Redux, without it. Could you provide more details or examples?

Collapse
 
javaguirre profile image
Javier Aguirre

Hello Seif! :-)

I don't think I said Redux provides a better testing environment. I cannot compare because I don't have the same experience using the Redux/Redux-Saga stack than using React Context API.

What I like about Redux and Saga is:

  • Data flow completely isolated from React components, so those are mainly presentational, and someone could only be working on those without needing to know anything from the data flow in the app. Using storybook for example.
  • Sagas takes care of all the impure actions, such as API calls, caching, etc. We can easily test it and it's completely isolated from anything else. You could develop that functionality using TDD, and It wouldn't affect anybody on the team.
  • We can use middlewares to validate data before going to the sagas, or for some logic not belonging on sagas or the React components. Easy to test too.

Maybe I misspoke when I said the best possible testing environment. I didn't mean mine, what I meant is testing is usually overlooked, and having a not optimal testing environment would lead to technical debt pretty quickly.

I'd like to know more about React Context API, useEffect and the rest of the new React magic โœจ, but what I've read didn't give me what I was looking for, do you have any examples regarding testing with React Context API so I could have a look?

Thanks! ๐Ÿ’ฏ

Thread Thread
 
seif_ghezala profile image
Seif Ghezala ๐Ÿ‡ฉ๐Ÿ‡ฟ
  • Using the context API doesn't necessarily go against separating data. Redux & the Context make it both possible to solve that issue by making it possible to create both providers and consumers of data. So afaik whatever you do with Redux to separate "data flow", you can do it without Redux as well.
    I found that the example in this article already shows a clear case where you can implement things without sacrificing a separation between the components and the data flow.

  • The reason I asked for examples is that I haven't yet seen a single concrete example that showed me something that only Redux can solve better ๐Ÿคทโ€โ™‚๏ธ.
    So if you do, please share it. Otherwise, I'm curious about what were you looking for in the new React features and that you didn't find? Examples of testing features?

  • Implementing isolated reusable components (e.g. a design system that you can showcase with storybook) can also be solved without using an external
    state management library such as Redux.

  • It's important to test features, and not test for testing. Testing API calls or tiny pure functions that update the state will give you more green checks on the terminal for sure. However, it's a false sense of achievement. I believe that good tests focus on testing features and not implementation details such as API calls, sagas or event a React context. Testing features shouldn't rely on such implementation details.
    At the end of the day, the user of our app doesn't care about how much "testing coverage" we have or whether we used Redux or React Context. The user only cares about how many bugs occur while using our application.

Thread Thread
 
misterhtmlcss profile image
Roger K.

Hi Seif,
I'm at risk here as a new new dev (I didn't stutter), however I do think that your comment about testing appears to take a position that I'm not sure I understand from what I've learned and been told, nor did I get from the person you have responded too as well.

I believe that those tiny checks aren't necessarily about displacing the user from the center as it seems you have assumed. As I've learned it's about making it easier for a developer to reason around the tests. I'm assuming unit tests and not integration tests. That's a reasonable assumption I think, right?

I find it easier to read small tests and grasp what's being tested. This in turn means when I add code it's easier to either add tests, see a need for a tweak to a test or what have you. It's true that this may lead to an error ultimately, but I don't think one set of testing displaces the other. Do you think that?

Personally I enjoy testing and find unit tests to greatly assist me in solving the problem better when I write my code (I do TDD mainly), however I also do functional testing both with and without the UI rendered. Is this not the best practice? I thought it was and if I'm right I don't think it's reasonable your last point as it takes a point of view that one form or type of testing has hegemony over another.

I do love your other points btw. I'm trying to determine if I need to use Redux anymore or can I move to the new Context API as my first choice.

Collapse
 
anssamghezala profile image
Anssam Ghezala

Thank you ! :D

Collapse
 
s4sbase profile image
Zah • Edited

Production code uses advance composition patterns and libaries like Redux for maintenance and testing. You don't have to use redux for your blog or a small app your building, but if you are building a real web app... use redux or another state management variant to scale your business effectively.

What we see is a lot of junior devs complaining about "unnessessary complexity" because redux has a steep learning curve. We need to look past this and let junior devs understand what real production code bases look like as they delve deeper into their careers and move up the corporate ladder or start something of their own

Collapse
 
yakimych profile image
Kyrylo Yakymenko

Very well said - this pretty much echoes my concerns. The notion that a state container adds complexity is somewhat misguided. It adds overhead and boilerplate - sure, but actually reduces complexity by making the application state transparent and predictable - an invaluable tool when debugging large codebases.

Good point regarding a "blog or small app" too - I have an article describing what happens when trying to build something of "moderate" size without proper state management not so long ago myself: Seriously - do React hooks replace state containers?

Collapse
 
tomino2112 profile image
Tomino

I would actually argue the exact opposite.
What I increasingly see is lot of mid-level devs mindlessly using tools just because they use them everywhere else regardless if their project actually needs it and establishing dictatorship over this because junior devs can't really challenge them. Usually when I see this in a company, at some point a senior dev comes in and almost always it results in mid-levels leaving project shortly after.

IMHO Redux is just an excuse to not having to think hard about your architecture.
Fundamental questions about development are like religion, you can never win discussing them.
Redux, scope models, Context etc. All been around for a long time and all are good tools to achieve end result, it is up to you to choose the right tool and use it well.

Collapse
 
patroza profile image
Patrick Roza • Edited

Nobody needs redux unless you have a really complex app, even then Iโ€™m not sure. Just use hooks; useState and useContext, itโ€™s enough for most apps. Often less indirection, thatโ€™s not just juniorโ€™s view. There are imo very few use cases that require global/shared state. Especially when you use GraphQL with eg react-apollo.
imo start the state at the component, and โ€˜upgradeโ€™ it up the tree depending on requirement, switching from state to context only once required

Collapse
 
yakimych profile image
Kyrylo Yakymenko

There are imo very few use cases that require global/shared state.

It's not as much about global/shared state, rather more about having state/logic tied to the component tree, which makes it painful, error prone and time consuming to make even simple layout changes. We end up moving state around the tree, instead of focusing on solving the real problems our users have.

Moreover, as the state end up sprinkled around the component tree here and there, it makes it even more difficult for new developers to come into this codebase and start doing something useful.

Collapse
 
patroza profile image
Patrick Roza • Edited

Donโ€™t see how it can be more complex, if the state lives close to where it is used. To me it seems harder once you start adding more indirection.

I think you can have state relatively close to its usage (page container) while remaining flexible to make layout changes. Just need to separate state handling from presentational components. Also it depends, sometimes you have presentational state, that usually lives just fine deeper in the tree.

Making custom hooks or hocs that manage specific state or behavior makes it imo also easier to grasp as itโ€™s more finegrained.

Not trying to suggest to apply chaos theory, structure is important.

Thread Thread
 
yakimych profile image
Kyrylo Yakymenko

I think you can have state relatively close to its usage (page container) while remaining flexible to make layout changes

True! Depending on who you ask, however, "page container" might not be considered "close to its usage". My concern is primarily about sprinkling state around individual components inside the page component tree.

Otherwise I completely agree - keeping state at the top level is conceptually similar to using a state container in that it achieves the same purpose.

Thread Thread
 
patroza profile image
Patrick Roza • Edited

โ€œpage containerโ€ might not be considered โ€œclose to its usageโ€

True in traditional data by props based components, but not when you adopt components by props and children;
See my response at dev.to/patroza/comment/bcnf

Collapse
 
flrnd profile image
Florian Rand • Edited

Redux is not hard to learn, yes, it's a bit verbose, but I think about redux as a toolbox where you have more control over the app state. That implies more code to write sadly. On the other hand, redux can be overkill depending on the app.

In my opinion redux also has a very nice official documentation enough to get you started.

React context seems pretty neat and easy to use. At the end is always the correct tool for the job right?

Nice comparisons, thanks for sharing!

Collapse
 
anssamghezala profile image
Anssam Ghezala

I see, thank you for sharing your opinion ! :)

Collapse
 
flrnd profile image
Florian Rand

Thank you for your article!

Collapse
 
jeserodz profile image
Jese Rodriguez

Redux has become way less verbose and intuitive after they introduced the Redux Started Kit. It feels like a modern and DX-friendly way to use Redux now, I recommend checking it out as the Redux ecosystem is great to build robust apps. redux-starter-kit.js.org

Collapse
 
jack profile image
Jack Williams

Great post!

We additionally use a HoC to make using the Context API easier. Something like this:

const withUser = (Component) => (
  (props) => (
    <UserContext.Consumer>
      {user => (
        <Component
          {...props}
          user={user}
        />
      )}
    </UserContext.Consumer>
  )
)
Enter fullscreen mode Exit fullscreen mode

Then to use it ...

const UserBookList = (props) => (/* props.user */);

export default withUser()(UserBookList);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
patroza profile image
Patrick Roza • Edited

Would suggest to use useContext, either directly, or in the HOC:

const withUser = (Component) =>
  (props) => {
    const user = useContext(UserContext)
    return <Component {...props} user={user} />
  }
Collapse
 
jack profile image
Jack Williams

Yep you sure could! The original example was without hooks, so I went that route.

Collapse
 
anssamghezala profile image
Anssam Ghezala

Thank so much for sharing this !!! :DD

Collapse
 
jack profile image
Jack Williams

You're welcome, hope it helps!

The Context.Consumer code scattered everywhere felt clunky.

Collapse
 
jasonsbarr profile image
Jason Barr

Note that Sebastian Markbage, a member of the React team, has said Context is not suitable as a replacement for a Flux-based state management system (such as Redux) in the case where high frequency updates to the state are necessary.

See this blog post (close to the end), which references commentary on this GitHub thread about the release of Redux 7 where apparently the Redux team had attempted to use Context internally with mixed results.

Personally, I tend to use Context for data I need across components that isn't likely to change (or change much) while the user is engaged with the application, such as information about the current logged in user.

Collapse
 
anssamghezala profile image
Anssam Ghezala

Thank you for sharing the blog post :)

Collapse
 
jasonsbarr profile image
Jason Barr

Thank you for your helpful article :)

Collapse
 
umezvictor profile image
Victor Umezuruike

Nice article. I think redux suits larger apps more than the context API,as it helps you track what's really going on behind the scenes, especially with the redux Dev tool. Context API is much ok for rapid development of small scale apps.

Collapse
 
anssamghezala profile image
Anssam Ghezala

Thank you :) I personally think that one should only use an external tool iff it adds more to what one has. So far I've only been working on relatively small apps, and I've mostly just been using React :) Thanks again !

Collapse
 
jaffparker profile image
Jaff Parker

Cool, I actually wrote about approach 3 (React Context) a little while back and the cool thing is that if you couple it with the useReducer hook, you pretty much have yourself a basic implementation of Redux!

You only need Redux now if you need plugins from it or anything specific to it (or if you're not using it with React and there's no context).

Collapse
 
fchwpo profile image
Shubham Vishwakarma

Both Context and redux serve different purpose if you just have to pass props to some inner children then go ahead and use context api or there are other better ways too you need not required redux in first place.

Collapse
 
radiesle profile image
David Amend • Edited

More creative 4. option: if input is not persisted to server, write it to URL, such as search filter for table. If it is persisted in DB, register to data change of serverdatasource, e. G. By websockets.

Nice comparison!

Collapse
 
iamawaisakram profile image
Awais Akram Mughal

Good post, But I agree to disagree, using context Api to pass multiple props in a single component will make it so much nested that you'd want to bang your head on the wall, but if you want to use beautiful context API try it with hooks ๐Ÿคค, you'll be amazed how easy to read code becomes, but for class components, redux is the best.

Collapse
 
anssamghezala profile image
Anssam Ghezala • Edited

I have started reading about hooks a couple of days ago ! :)) Thank you !

Collapse
 
tapaibalazs profile image
Tรกpai Balรกzs

Nice article!

I believe the Context API could be more useful (in certain situations at least), because you are not limited to only one context.

You can create multiple contexts and use them at their places. For example, I can imagine a context related to the user/login state and another context related to application specifics and whatnot.

I don't have much experience with redux, but to me, it feels like it is an excuse for global variables. I'm not so fond of keeping everything in one place. Adds unnecessary complexity. :)

Collapse
 
_saranshbarua profile image
Saransh Barua

This is a really well-written article. Clear and concise! Great Job :)

Collapse
 
anssamghezala profile image
Anssam Ghezala

Glad you liked it ! Thank you !

Collapse
 
johnmunsch profile image
John Munsch

Another good reason to use Redux is that your state management is independently testable and because it is component system independent. So, if you're transitioning off of React to a Web Components based system in the future then your state management still works and isn't tied to React specifically.

Collapse
 
schoettkr profile image
schoettkr

Great article! The redux example didn't seem to work for me, I made some small changes: codesandbox.io/s/reduxtree-8vs2f

Collapse
 
kayodeadechinan profile image
Kayode Adechinan

Thanks

Collapse
 
anssamghezala profile image
Anssam Ghezala

Youโ€™re very welcome! Thanks for reading!

Collapse
 
patroza profile image
Patrick Roza • Edited

@anssamghezala added my thoughts on alternative to props drilling: Component vs Prop Drilling

Collapse
 
awmleer profile image
awmleer

Based on Context API, I made a small library called Reto. Now I use it everyday and have thrown redux away completely. awmleer.github.io/reto

Collapse
 
anssamghezala profile image
Anssam Ghezala

WAW! Amazing โœจโœจ

Collapse
 
karataev profile image
Eugene Karataev

According to the comments, it seems the only way to structure big React apps is Redux.

Collapse
 
galih56 profile image
Galih indra • Edited

After reading all these comments and things make me realize that I'm still very new at this. You guys are doing great. Thanks for the article Anssam. Hope to see your another article soon :D

Collapse
 
anssamghezala profile image
Anssam Ghezala

Hey there :) Glad to see you enjoyed it! I actually published other articles you can check em out here: anssamghezala.netlify.com/publicat...!

Collapse
 
rawad663 profile image
Rawad Karam

It's very common to think that as soon as you want data to be shared across multiple components that Redux is always the go-to, but it's not!

Great read ๐Ÿ˜

Collapse
 
n1th1l profile image
N1TH1L N

In one of our project we used context API. Since we are passing another component as a children to it & it was very difficult for CSS team do flex positioning.

Collapse
 
zxdong262 profile image
ZHAO Xudong

I would give another answer: Subx: github.com/tylerlong/subx

Collapse
 
anssamghezala profile image
Anssam Ghezala

Oh wow I've never seen this before :O Will definitely check it out ! Thank you for sharing ! :))

Collapse
 
chadsteele profile image
Chad Steele

Great article! Thanks!
I think you'll like this alt to redux as well.
dev.to/chadsteele/eventmanager-an-...

Collapse
 
abid_rahim_ profile image
Abid Rahim • Edited

Hey Anssam, very well compared. I couldn't understand this part though

"Our Provider component has as children all the components from which we want to access the context data."

Collapse
 
chadsteele profile image
Chad Steele

I'd love it if you wanted to dissect my Redux one line replacement hook... useSync
dev.to/chadsteele/redux-one-liner-...

Collapse
 
dennisat profile image
Dennis

You don't have to use Redux because the boilerplate is so f... big!
Have you tried Dynadux? github.com/aneldev/dynadux It is much simpler and powerful.