8 ms·
There is a certain paradox with teaching something like Redux, in that it's designed to make complex systems easy to understand and manageable. Yet when trying
by robmcm 9y ago
There is a certain paradox with teaching something like Redux, in that it's designed to make complex systems easy to understand and manageable. Yet when trying to demonstrate with a simple example, it appears hugely over complex and unnecessary.
I think a pre-requisite to learning something like Redux (or any micro-architecture) is to first try building something without it. Once you understand the pains of undisciplined, organically designed, spaghetti applications, the cynicism is replaced by excitement over how this will improve your job/life/application.
- dceddia 9y agoThis paradox I think is what turns people off Redux when they first learn it. "All this code... for what benefit?" Of course it's total overkill for something like a counter, or a todo list, but it's tough to teach an introduction to something by starting with "here's a huge enterprise app, let's dive in" :) I tried to call this out in the article to make sure people are aware that improving simple Counter examples is not what Redux is really meant for. I'm considering putting together a larger course/book that does just what you say - build up a React app using plain state until it becomes painful, and then refactor it to add Redux. My question right now is, how far should I go? Do I walk through building the entire app with state (and push through the complexity), or do I give up at the first indication that Redux would make things easier?
- rahimnathwani 9y ago> "here's a huge enterprise app, let's dive in" I'd love to see a complete project that uses redux, and would be horrible without it. Any pointers?? :)
- kolme 9y agoHere's a tool you most likely used at some point :) https://github.com/devtools-html/debugger.html https://github.com/devtools-html/debugger.html
- buzzier 9y agohttps://github.com/cvdlab/react-planner https://github.com/cvdlab/react-planner
- acemarke 9y agoI'm a Redux maintainer. Here's my two standard suggestions for more realistic sample apps: - An 8-part "Build a Simple CRUD App with React and Redux" tutorial: http://www.thegreatcodeadventure.com/building-a-simple-crud-app-with-react-redux-part-1/ http://www.thegreatcodeadventure.com/building-a-simple-crud-... - My own "Practical Redux" tutorial series, which shows off specific useful React and Redux techniques within a sample app: http://blog.isquaredsoftware.com/series/practical-redux/ http://blog.isquaredsoftware.com/series/practical-redux/ Also, my Redux addons catalog has a page listing many other interesting Redux-based apps, including purpose-built samples and real-world apps: https://github.com/markerikson/redux-ecosystem-links/blob/master/apps-and-examples.md https://github.com/markerikson/redux-ecosystem-links/blob/ma...
- tootie 9y agoI understand the value of redux but I'd lump it in with git as an invaluable and elegant solution with a terrible interface. The structure is very confusing up front and makes no sense to an outsider. I learned react in about 15 minutes because it's so intuitive, but redux keeps making me scratch my head. IMO, It's a fundamental flaw with JavaScript that interfaces aren't rigorous or discoverable and redux is a willing victim.
- acemarke 9y agoCan you clarify what you mean by "terrible interface" for Redux? What structure is "confusing"? Is this a concern with docs, the core Redux store API, the React-Redux API, or something else? Any suggestions for how we can improve things?
- tootie 9y agoI think it's mostly react-redux. There's arcane boilerplate in the connect function, mapDispatchToProps looks like a leaky abstraction, actions being passed as objects with a string in them is super brittle. I don't have a fix, but I think just being able to inject a link to the store and then having an API that can be manipulated directly from the component would more comprehensible and cut down on the layers of indirection. I typically see corresponding action, reducer js file for a component when 95% of the logic is already in the component. Just merge them.
- acemarke 9y agoAppreciate the feedback. Could you give specific examples of what you mean by "arcane boilerplate" and "leaky abstractions"? We don't have any plans to change the actual API, but I would genuinely be interested in any suggestions or concerns you have with it. It's also worth noting that I personally highly recommend consistently writing separate action creator functions [0], and using the "object shorthand" argument to `connect` instead of writing a separate `mapDispatch` function. That said, it also seems like part of what you're concerned with is the fundamental design of Redux. The use of plain object actions as a layer of indirection is deliberate [1], and it's what enables capabilities like time-travel debugging. Actions need to be serializable for that to work, and therefore strings are the best solution for the action's `type` field [2]. You certainly don't have to keep _everything_ in Redux. You should consider whether a given bit of state should live in Redux, or in a component's state [3]. But, if you _are_ going to keep data in Redux, then actions and reducers are necessary for the Redux data flow. They don't have to be in separate files [4], but they need to exist to update the store. [0] http://blog.isquaredsoftware.com/2016/10/idiomatic-redux-why-use-action-creators/ http://blog.isquaredsoftware.com/2016/10/idiomatic-redux-why... [1] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao-of-redux-part-1/#how-redux-actually-works http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao... [2] https://redux.js.org/docs/faq/Actions.html#actions-string-constants https://redux.js.org/docs/faq/Actions.html#actions-string-co... [3] https://redux.js.org/docs/faq/OrganizingState.html#organizing-state-only-redux-state https://redux.js.org/docs/faq/OrganizingState.html#organizin... [4] http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao-of-redux-part-2/#defining-actions-action-creators-and-reducers-in-separate-files http://blog.isquaredsoftware.com/2017/05/idiomatic-redux-tao...
- Waterluvian 9y agoThis is exactly what happened to me and I'm glad I did it. My intro to programming was a nightmare jquery app. Then a slightly better Backbone app with too many Globals. Then an over engineered Sails app. And now a collection of React + Redux apps, multiple years old, each with increasing levels of maintainability. I'm hesitant to see new programmers avoiding a "learn the hard way" project. Without it, there's so much they might never grok.
- eqmvii 9y agoJust went through this myself, and that was exactly my experience. Really glad I spent time working with React so I knew what Redux would be great for before I tried to learn it.
- koolba 9y ago> Once you understand the pains of undisciplined, organically designed, spaghetti applications, the cynicism is replaced by excitement over how this will improve your job/life/application. Beautifully said. The same goes for schema-less data models. The full appreciation of foreign keys, data type validation, and check constraints doesn't kick in until you try incrementally changing a NoSQL spaghetti app.
- danenania 9y agoSimilarly, I've always liked javascript's dynamic and flexible nature, especially for ui programming where requirements evolve quickly and dramatically. But now that I've got a big redux app that is on a pretty steady course, I'm starting to see the value that static types would bring. A lot of the mental overhead of working with the codebase now consists of remembering the exact shape of all the data, which properties are defined on which actions, etc. Before too long I'm going to have to give Typescript, Flow, or something along those lines a serious look just for the sake of having it all defined in one place.
- koolba 9y agoI've been singing the praises of Typescript since the first day I started playing with it. Easing into it from a JS codebase is pleasant enough, but greenfield development with typing everywhere is incredible. I highly encourage checking it out sooner rather than later.
- ryanbrunner 9y agoI think there's a fair criticism of Redux in here - most well designed tools can accomodate a learning curve, and scale up the complexity when needed. I can be productive in Express without knowing about middleware, or git without knowing how to rebase. Redux, on the other hand, expects you to dive into the deep end head first the first time you use it. I teach javascript development, and I'm noticing there's a pretty big gap where you're feeling the pain of React, but Redux is still too large a complexity tax (To be fair, even to an experienced programmer it often is - for every complex state change that warrants Redux there's 50 straightforward "change this field" or "toggle this boolean" actions.) Maybe this isn't the responsibility of Redux, and something should be built on top of it, but there needs to be some amount of consensus on what the best solution is.
- travmatt 9y agoHave you ever tried MobX? I haven’t tried it, but have heard it is kind of in that mid point between react state and redux
- ryanbrunner 9y agoYeah, personally I use it - I think it hits the sweet spot of making simple things simple while still allowing for complexity perfectly. It's a shame I can't really teach it, however - the fact is, it doesn't have enough mindshare right now and part of the reason people take courses is to learn marketable skills. For better or for worse, nearly every React shop is looking for devs who know Redux.
- ccalvert 9y agoI perhaps foolishly go ahead and teach React and Redux to my students. The first thing I show them, however, is this article by Dan Abramov, who you perhaps know from his conference videos or his amazing work fielding React bug reports. You might not need Redux: https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367 https://medium.com/@dan_abramov/you-might-not-need-redux-be4... The little example he provides is remarkably powerful and a great intro to thinking like a Redux programmer.
- emodendroket 9y agoMy only experience of using Redux was in a completely inappropriate application and I really came to hate it, but I can see how it'd be cool if you wanted to do like... a word processor or something where you wanted an undo/redo chain.
- irl_zebra 9y agoI agree with this. I tried to learn React and Redux a while back, and didn't really grok it, so I built the React app without Redux. Ended up passing state up and down many, many layers of components and it got pretty hairy. So I added Redux to the mix and it was like a lightbulb went off in my head.
- krishanath 9y agoThat's because you used React Router, which makes the router a view component. Router should be independent of view technology. If you had used React in the MVC style you would not have had to use Redux. Think about how session state works in the case of server-side applications. The same can be done on the client side too, by using React with an MVC framework.
- krishanath 9y ago>> it appears hugely over complex and unnecessary Which it is, actually! Think about how MVC works in iOS, or ASP.NET MVC or JSP Model 2, etc. In the case of the latter two, your state is stored in the session as simple, regular objects. Have you felt the need for actions and reducers and immutability etc. when using session state? I have not. When programming JavaScript SPA, you can program in the style of MVC also. There is no need for actions, reducers and so on, unless your app is for example a word processor and you need undo/redo (as mentioned by another comment on this thread.) Most of the time you are getting data from the backend, temporarily storing stuff in memory, modifying it and sending it back to the backend. There is no need for actions/reducers and such other nonsense for that. When I mention this someone always points me to the "you may not need redux" article by the creator of redux, in an attempt to legitimize some use cases of redux. There may indeed be some legitimate uses cases for redux. But it has become the de facto standard way of building React applications, and that's totally unjustified.
- beaconstudios 9y agoMVC isn't especially easier than event sourcing (which is basically what redux is) once you get to larger applications. I think the two map quite nicely onto Fowler's design stamina theory (https://martinfowler.com/bliki/images/designStaminaGraph.gif https://martinfowler.com/bliki/images/designStaminaGraph.gif) in that redux is harder to work with for small apps but the complexity scales linearly. MVC is easy for small apps but has a tendency towards spaghetti in larger codebases.
- krishanath 9y ago>> MVC is easy for small apps but has a tendency towards spaghetti in larger codebases. Disagree. There is no reason to believe MVC tends towards spaghetti in large codebases. Controllers and views implement a small portion of the application's functionality. When the applications get larger individual controllers and views do not even know that the application got larger, so this scales very well.
- dceddia 9y ago
- lewisl9029 9y agoI've always been a huge fan of Redux, but lately I've become even more enthusiastic about Apollo Client 2.0 and the apollo-link-state project: https://github.com/apollographql/apollo-link-state https://github.com/apollographql/apollo-link-state What this will let you do is basically extend your server-side GraphQL API with a set of local resolvers for queries and mutations, and let you query and mutate both your server-side and client-side state using a single consistent API (GraphQL, with client-side fields decorated with a @client directive), backed by a (mostly) automatically normalized local state cache (by default apollo-cache-inmemory, but customizable, so you can even implement a Redux based cache if you'd like more control). A lot of the complexity in Redux today stems from the need to reconcile client-side state with server-side state, usually fetched through some kind of async actions paradigm like Thunks+Promises, Saga, Observables, etc, to be then manually merged into the local state after being transformed into a normalized form. I personally think one of the biggest problems with the design of Redux is that the architecture derives most of its benefits from having a normalized state tree, but it also makes it all too easy for developers to store non-normalized data in the state tree. Although admittedly an architecture that does enforce a normalized state tree would be an order of magnitude more difficult to learn and work with in the wild-west of RESTful APIs that used to be the de-facto norm back in the days when it was designed (and it still is, though that may be slowly changing with the rapid adoption of GraphQL), where most server-side data you receive isn't easily normalizable to begin with. A good GraphQL client like Apollo can already abstract away much of the complexity involved with async server requests through its Higher-Order Component-based API, which simply provides data to the wrapped component as props, so it doesn't need to know how to fetch that data. More importantly though, Apollo also ensures that all the server-side state it maintains in its cache is stored in a normalized manner, and GraphQL makes this fairly easy. Apollo-link-state goes a step further and allows you to use the same abstractions for managing client-only state, and store it in a normalized form alongside your server-side state, to allow for a much more consistent and comprehensive state management API. With all that said, apollo-link-state is still really young and I've only played around with it briefly in toy projects, so there's no guarantee it could scale as well to large teams as Redux has. I do still personally find it to be one of the most promising alternatives out there though. Lastly, Relay Modern also supposedly has something called Client Schema Extensions, which I assume is similar to apollo-link-state, but wasn't able to find any documentation on it outside of a brief mention in its release notes: https://facebook.github.io/relay/docs/new-in-relay-modern.html#client-schema-extensions https://facebook.github.io/relay/docs/new-in-relay-modern.ht...
- acemarke 9y agoYeah, Dan Abramov made a great comment a few months ago, which I posted on Twitter ( https://twitter.com/acemarke/status/901329101088215044 https://twitter.com/acemarke/status/901329101088215044 ): > Dan Abramov, just now : "if you want to teach someone why to use an abstraction, you should first make them feel the pain of not having it" But yes, it's tough to try to show the value of Redux while at the same time keeping the example simple enough to illustrate the basic mechanics.
- hesarenu 9y agoYou could always try something simpler like mobx.