Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Ask Redux users what problem it is solving for them and watch them squirm. Eventually they will come up with time travel debugging, or replaying state changes, etc. This is developers working backwards and inventing problems to justify their technical choices.

Not coincidentally, most blogs about Redux jump right into how to use it, without prefacing it with why would you want to use it in the first place.

A lot of developers think introducing more libraries and more rigor is a good thing even if it drives up the cost of software development. This is the only reason I can think of, for why so many people are using Redux. Another reason may be ReactRouter which makes it harder to supply data to React. But there are other MVC routers that make using React painless and I'd recommend to anyone considering using ReactRouter/Redux to consider better MVC-based alternatives. (And no, using MVC does NOT imply two-way data binding.)



I would flip that first paragraph around. Time travel debugging and replaying state changes are technical solutions that were created to help solve one of Redux's core use cases: making it easier for a developer to understand when, why, and how your state was updated, and what part of the application triggered that state update. In addition, centralizing large portions of your app's state enables a wide variety of useful capabilities.

I do agree that many people and articles talk about the "how" rather than the "why", but I'd say that this is a widespread issue rather than being specific to discussions of Redux.

Dan Abramov, Redux's creator, has said himself that "Redux is over-hyped". I also agree that many people are being pushed to learn it without understanding why they ought to use it, and that new learners are being told they _must_ start with Redux and React at the same time. That's not what we encourage officially - we suggest that people start with React first, then learn Redux later.

However, I think saying "people only use Redux because it's hyped or they're told to" is both inaccurate and unfair. I've talked to many people who have said that Redux is helping them write better-architected applications that are more maintainable and easier to work on. Some people may have chosen it due to hype, but many others have chosen it because it solves their problems.

Finally, I'd like to recommend reading Dan's article "You Might Not Need Redux", which discusses the tradeoffs involved with Redux, both the limitations it asks you to follow and some of the potential benefits you get in return: https://medium.com/@dan_abramov/you-might-not-need-redux-be4... .


>> making it easier for a developer to understand when, why, and how your state was updated, and what part of the application triggered that state update

What percentage of business applications would benefit from this? My guess is, very few. Typical business applications fetch data from the backend and display it, let the user update the data and immediately send the updated data to the backend. There is no need for something to track "when, why and how your state was updated and what part of the application triggered the state update". I am not saying nobody needs that kind of capability. I am saying that few business applications do, and yet there is this notion that React and Redux go together and if you're going to use React it would be strange to not use Redux. Practically everyone who uses React also uses ReactRouter and Redux.

The end-result of this is that React, which by itself is a simple, elegant and useful technology, has been turned into an over-complicated mess by the community of developers, by gluing it with over-complicated add-on technologies.


Why limit this to "business applications"? There's a whole lot more apps out there than just those :)

If an app is really _just_ fetching data, displaying it in a row or form, and sending it back, then there might not be a lot of benefit. However, if data is being shared across multiple pieces of a UI, and the user is interacting with that data in multiple ways, then there may be more benefit.

And yes, my own estimates are that roughly 55-60% of React apps are using Redux as well.


Definitely. if an app is just fetching, displaying and mutating data, Relay Modern and Apollo Data are -> that way.


It's not the same -- Relay Modern and Apollo Data are both a bit half-baked still in terms of client-side state caching. GraphQL mutations are painful to code right now. I say all this as a long programmer on my side SaaS -- with a team, things aren't quite so bleak. I really want to go GraphQL but it's just too complex still. Redux is much simpler to reason about. It is a simple state store. The client side state caches are just not there yet from what I can tell. There is too much magic and not enough time on the market to trust my business with them.

I'd love to hear contrary experience.


Well, what's your solution?

I mean, I've seen people drop redux into a single stand alone form for no reason other than they hadn't used react before, so they picked up a tutorial and the first thing it said to do was use redux.

So, I'll happily agree that there's a whole lot of people using this without any need for it.

...but there is a need for it for some people, and for those people, what's your alternative? Raw react? Have you actually tried that? Passing all the props down from child to child to child to child? It's not awesome, I assure you.

Are there redux alternatives out there that solve the same 'single source of truth' problem I've never heard of?

What are you using?

> There is no need for something to track "when, why and how your state was updated and what part of the application triggered the state update".

...or is that simply not a problem that some people have? I'll certainly agree to that; but then, why are you using react?

If your UI isn't dynamic, why are you building an SPA? For fun? The good old MVC tech stack works perfectly well for static data display and forms.

You know why react exists? ...because complex interactive forms are hard to do right, and because interactive user interfaces that do something more complicated than CRUD operations are actually quite difficult to do right.

The MVVM pattern with data binding is the 'best' solution out there for most UI application framework, and react is successful specifically because it allows you to manage complexity by creating a hierarchy of components instead. That's a really powerful effective technique, there's no question.

Redux lets you manage the state for that hierarchy in one place. It lets you build large react hierarchies and know exactly what state the UI is in at any point in time, in one place. Why? ...because managing state in 100 different locations is complicated.

What you're seeing is tools to help manage complexity; but you only need to use them when your complexity reaches a threshold that triggers the need to use them.

If you don't have a complex problem, you don't need complex tools to manage it.

> has been turned into an over-complicated mess by the community of developers, by gluing it with over-complicated add-on technologies.

What you're seeing is the application of tools to solve a problem that doesn't exist for the specific domain you're looking at.

That doesn't mean they don't solve the problem; it just means your problem doesn't require that level of complexity management.

It's quite frustrating.

I hear the 'its too complex' as an argument from so many people about using libraries and tools, and want 'something simple' instead; but I've hardly ever heard someone pitch a viable alternative instead, just complaints. Too much tooling. Too much complexity. Over engineering.

So, tldr: When you do have a big complex react application with complex UI interactions... what's the alternative?

If there is one, I'd like to hear about it.


> Have you actually tried that? Passing all the props down from child to child to child to child? It's not awesome, I assure you.

I honestly think its not that bad. Elm essentially does that, and its arguably more productive than React's ecosystem.

You might just want to optimize things a bit by making non-leaf components take a simple "model" prop (that contains all the properties they need) to reduce friction a little, but aside for that it might even make code better by forcing a more thoughtful component hierarchy.

After all, if component A renders component B, then A really DOES depend on B's props. Magically having B kinds of hide dependencies.

After all, short of using DI containers, if I have a function that calls another function that calls yet another, I DO pass arguments all the way down. And React components are semantically just functions.


Only at a relatively trivial scale; and certainly, do that if your application is simple enough. There's probably a fair number of applications that clearly fall into the 'simple enough not to need redux' category.

That's a good approach, seriously. You don't need redux at that point; don't use it. I'm not even suggesting such applications are 'trivial'; they probably just don't have excessively complex component hierarchies and interactions.

...but please read this really quite old article if you haven't before: http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/

This is an argument that has literally been made a hundred or more times before, and nothing has changed about it.

Sure, this article is about dependency injection, but its essentially the same domain. You can argue that manually passing props is the same of 'poor mans' dependency injection, and it certainly has value in that there's 'no magic' in it.

...and certainly, you fall into the pit of pointlessness and frustrations when you use magic, but there's no convention to make the magic 'all work without surprises'; but the same issues still apply.

Once the application reaches a certain size, the maintenance burden of the 'simple' approach becomes prohibitive.

/shrug


I am evaluating whether or not to use one of these state managers (vuex in my case) at the moment. I looked over the original facebook talk about flux and I am kind of getting the feeling that this is one of those solutions to a problem I don't want to ever have. It isn't about how complex your app is, but rather, how complex your organisation is.

A lot of these solutions, like static typing in non-performance areas, and so on, are about "how do we get this new engineer to start working on code that he has no idea about quickly". This problem only exists in large organisations and I personally don't think large organisations are very good at anything so don't care about those set of problems.

Basically it comes across as another "how do we hire large numbers of average programmers" problem and the facebook talk said exactly that. State managers, like dependency injection, just add another level of indirection that make your application harder to debug. You can no longer just follow a simple chain of methods, because everything disappears into the magic land of the state manager as soon as you start using (as the vuex example) store.commit("increment", 10); instead of actual methods and so on.


I'm not going to continue repeat the arguments which have been made exhaustively about the benefits vs. draw backs of these approaches by other people. There are plenty of articles which cover this topic... all I can say is please read them.

If you still don't see any value in these tools, don't use them.

All I'll say is this:

In my experience, people tend to consider their applications to be simple enough that a simple solution is sufficient.

However, in reality, that seldom seems to be the case.

UI is hard to get right, and has a tendency to drift towards complexity over time as more features are added: I can think of several people who have picked the naive simple solution and regretted it later; to the point of rewrite in some cases.

People who picked the complicated solution sometimes regretted the extra burden of complexity, but I don't think I've ever seen this as a cause for large scale failure or rewrite.


I agree. I have written large applications with client-side rendering and they do get very complex. I am still just trying to debate the topic rather than claim to know the answer.


You also have to figure out how you are going to deal with debugging access to the state. Sometimes you don't even know who is modifying the state. Add in asynchronous programming, and you have all kinds of modifications going all in all kinds of orders from all over the place and you have to figure out:

the order of the modifications

who performed them

how they modified them

So the state manager adds that in as well. You can add getters and setters and enforce synchronous programming in certain methods, but then you are 90% towards a state manager.


Here is my solution.

https://github.com/tjdavies/copal

Its basically the same as Redux in intent but nicer to work with. It even supports the redux dev tools


Have you considered using MVC? It works well. Search the complementary tools page of React.


For me, there's a peace of mind associated with knowing that all my state is in one place in an organized format. It's like having a db, but on the front end, and it makes testing the front end very nice. It also has other practical benefits.

Specifically, 1) it makes rapid iteration simpler because I don't have to click back to the portion of the app that I'm testing but can instead just rehydrate a cached state, and 2) it makes it trivial to save state for the user either by caching it locally in the browser or by sending it over to the back end.


Why do I need Redux for that, though?

I'm working on a fairly small but still nontrivial React app for work (it's the first time we've used React for anything here, and we're partly doing it to evaluate React for future work). I've not used Redux anywhere in my application (it's all vanilla React), but my state is still all in one place in an organized format, and, since I have a single component managing my state, I can still trivially do both (1) and (2) there.

What's Redux giving me that I don't already have, aside from another layer to maintain and another piece to break?


I wrote an article a while back that describes some of the possible benefits for using Redux in a React app: https://www.fullstackreact.com/articles/redux-with-mark-erik... .

Quick summary: you don't have to pass data as props all the way from the top of your app to the bottom, and it lets you keep your app state if you're doing hot module reloading in development.

In addition, time-travel debugging and the action history log really are powerful tools for understanding how your app is behaving over time.

My other comment just below this discusses some more benefits, and links to Dan's "You Might Not Need Redux" post. I'd encourage you to read that as well.


> you don't have to pass data as props all the way from the top of your app to the bottom

Quick note, you can accomplish this directly using the "context" feature of React, which is what Redux uses under the hood anyway.

https://facebook.github.io/react/docs/context.html


Yeah, I was keeping the explanation shorter.

The React docs generally advise that apps try not to use context directly, as the API has limitations, and _will_ change in some future React release once they figure out a better approach. The main issue is that context updates are blocked if a component returns `false` from `shouldComponentUpdate` (and the same for a PureComponent). As a result, context is best suited for references that won't change, such as pubsub event emitters.

Michel Weststrate's post "How to safely use React context" [0] is excellent, and Ken Wheeler just gave a good talk about context at React Boston [1].

[0] https://medium.com/@mweststrate/how-to-safely-use-react-cont...

[1] http://reactboston.surge.sh/#/


As someone who went from using context to using redux, you can really shoot yourself in the foot with contexts. With redux we can breath again.

Contexts is useful for anything that rarely changes. Like callbacks. But if you want to send down stateful things it will quickly become a mess for complex apps.


"I don't need redux because I implemented something to do the same thing it does myself" is not an argument against redux. You may not like redux but you do understand it's doing something necessary, so people who like it's implementation should probably use it.


> It's like having a db, but on the front end

eh. Not really. Because there is no schema, what happens is the Redux store turns into a mess.

You got 10, 20, 30 developers working on an app, no one has a clue what any of the Redux variables mean or what use-case they are for (or what use-case they may change), and worse you have redundant data scattered everywhere and you're never sure which should be the authority. It's an ad hoc global variable soup that is updated with the moral equivalent of GOTOs (Redux actions) that litter the code in just about everywhere you could possibly think of.


Right. It's like a db iff you have and enforce a convention to keep your data organized.


> It's like having a db, but on the front end

This.


I like Redux because tracking mutability and specially, side-effects that cause it, is a bitch once your app stops being a special snowflake you alone created and cared for a small purpose.

Even for those small applications/prototypes, having a centralized store allows me to code on auto-pilot where I don't have to worry as much about the code and focus on what it does instead. Would X particular piece of UI work better in a different way? Okay, then that UI code can fuck right off; it's not like it's going to affect the rest of my application's state.


You might also want to look at what people used before redux. There were a lot of Flux libraries and they were not all easy to use. And skipping libraries for state management all together often ends up in writing spaghetti code or reinventing the wheel. A small state management library can help a lot.

I used a Flux library before but like mobx now and will default to that unless some specific requirement point to redux or something else.


React is nice because it encourages encapsulation and componentization. Redux feels like it discards all that. Your OO encapsulation gets disassembled into pure functions and dumb state. Pure functions are great to reason about, but redux applications feel like they have their insides extruded and thrown everywhere.


Globalization and encapsulation are different points on a spectrum, and both have benefits and disadvantages. It's all about tradeoffs! :)

I've definitely noted that React devs seem to fall into either a "component-centric" view of the world, or an "app-centric" view. Both are okay.

I'll also point out that the Redux FAQ explicitly says it's up to you as a developer to decide what state should live in Redux, and what is better suited for local component state: http://redux.js.org/docs/faq/OrganizingState.html#organizing... .


I jumped in the Redux bandwagon after spending the decade before that either in jquery hell (or pre-jquery hell), and eventually Backbone, Angular, and React + Flux.

I've touched probably 200+ production frontend apps of various sizes by now, ranging from a couple of pages, going to tens of millions of lines of Javascript in a single monolith.

Your millage will vary and everyone hits different challenges in their career, but to me, the biggest issues when building apps was never building them from scratch or adding new features. It was always maintaining existing features. So I optimize everything I do for that, as I consider everything else completely trivial except for groundbreaking algorithms designed by PhDs (which is not me) and not worth thinking about.

I've spent years trying to nail down why these apps, no matter who works on them, always end up impossible to deal with. No matter how much time is spent trying to figure out the architecture, documentation and design, it always goes to hell given enough time.

To me (and its a totally personal analysis), it was always nailed down to figuring out: "Where the F* does this value come from" or "how do I follow what the hell this button does". It should be simple. I can use a debugger, obviously, but as requirements pile on, it invariably goes to hell.

Elm, to me, is the panacea of solutions here. A single atomic state, and a UX that is nothing more than a projection (or a map, if you prefer) of state to UX.

And to keep the UX "dumb", you then need to externalize all state and side effect logic.

Once you have that, you can reason about any bug without even looking at the code. Is the UX wrong? Was the state right? No? Did the event triggered right? yes? Well, the bug HAS to be in the update function. Boom done.

Now the question becomes, how do you reproduce this in JavaScript, which doesn't even have an approximation of algebraic effects, doesn't have immutable data structures, doesn't have a good way to play with the dom in a declarative way...

React + Redux with a few extras from the ecosystem provide that. Who cares about boilerplate, I get predictability. The more you abstract, the less predictable things get and bugs can come from anywhere.

Inevitably as the app grows, you need to add stuff and weave it in the existing features. The decoupling of State <--> Selector <--> Component <---> Action <---> Reducer has a very tightly defined set of semantics where even the most complex requirement fall neatly in these atoms (not quite as neatly as Elm when it comes to side effects, but it's as close as I've found for now).

Build an app some other way that does the -exact- same thing? You'll either end up with just as much code (oh, it won't be as repetitive and boring, but it will be there. I LOVE boring code), or you'll end up with something much more rigid that requires more compromises. There's a few alternatives that get close, but they usually do so by tightly coupling concerns and making it harder to figure out where the hell shit is happening.

The only obstacle is that the reasons behind "why" things are done this way is almost lost to most people working with Redux, in spite of Mark's best effort to prevent it from happening (there's only so much he can do short of brainwashing the planet). When the "why" gets lost, the community starts building things that neuter Redux, making it seemingly useless vs the alternatives.


I have to say this near perfectly mirrors my experience. We have a JS application [1] that is getting fairly large in size and development is moving quickly. Before we introduced React + a Redux style pattern (we don't actually use the libraries but have borrowed heavily from the pattern) we did find it difficult to track down bugs and making changes to existing features became a minefield.

I feel the pattern has helped as the team has grown. Yes there is boiler plate, but that boilerplate makes it hard to deviate from the pattern e.g. if you want to update the application state, you must dispatch an action, no way around it. In the past with MVC/MVP style patterns responsibility get muddled and you get a lot of inconsistency in implementation.

I've got no data for it, just observations, but since we have switched a to more functional style of programming and using immutable data, we are encountering less bugs which I put down to side effect free code.

Overall we have had a positive experience with React + the Redux pattern. Yes you could do this with other frameworks and patterns, but it works well for us and no doubt the same argument could be applied to whatever framework others are currently using.

[1] www.barvas.com


The "You Might Not Need Redux" blog post by the author of Redux addresses your points almost directly: https://medium.com/@dan_abramov/you-might-not-need-redux-be4...

The TL;DR is Redux tries to place a set of constraints on how and when you're allowed to share state between components and how and when you're allowed mutate that shared state, much like how React and it's virtual DOM abstraction places constraints on how and when you're allowed to manipulate the DOM.

These constraints allows the library to make certain assumptions about state and state changes that enables it to perform global performance optimizations across the entire codebase (namely performing only shallow equality checks on all state-mapped props when determining whether or not to rerender, because it can assume all state changes will result in a reference change) that would otherwise have to be performed for each component on a case by case basis, and micro-optimized by each individual developer by hand.

These constraints also allows tooling authors to make these same assumptions, which is what enables the best-in-class tooling that Redux developers have access to, like time traveling debugging and state change replays. These tools would simply not be possible to build in a generalizable way if your codebase didn't allow them to make the same assumptions (and adhere to the corresponding constraints when it comes to state sharing and state mutations) as it could for a Redux codebase.

The post has a whole list of very compelling use cases/tooling that are either made possible by or at least made completely trivial by the enforcement of these constraints around state mutations:

> These limitations are appealing to me because they help build apps that:

> Persist state to a local storage and then boot up from it, out of the box.

> Pre-fill state on the server, send it to the client in HTML, and boot up from it, out of the box.

> Serialize user actions and attach them, together with a state snapshot, to automated bug reports, so that the product developers can replay them to reproduce the errors.

> Pass action objects over the network to implement collaborative environments without dramatic changes to how the code is written.

> Maintain an undo history or implement optimistic mutations without dramatic changes to how the code is written.

> Travel between the state history in development, and re-evaluate the current state from the action history when the code changes, a la TDD.

> Provide full inspection and control capabilities to the development tooling so that product developers can build custom tools for their apps.

> Provide alternative UIs while reusing most of the business logic.

You could certainly make the case that Redux is not necessary for building a React app. Or the case that the additional boilerplate and constraints it places upon you could be a net negative for apps that are not sufficiently complex to warrant them. In fact, that's exactly the case that the linked post tries to make.

And yes, the only reason people use Redux is to introduce rigor (constraints) into their codebase and development workflow. But to insinuate that the rigor and constraints introduced by Redux will only ever be a net negative in terms of developer productivity is to display a fundamental ignorance regarding the vital role that rigor and constraints have always played in software architecture, and the fact that the recent advances in frontend architecture that have been proven to reduce complexity and make large codebases easier to reason about (things like the virtual DOM, unidirectional data flow, immutable state trees/caches, functional/reactive programming, and even the MVC pattern itself) have almost always come as a result of placing more constraints on what the developer is allowed to do.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: