6 ms·
Redux-query – A React/Redux library for querying and managing network state
- stymaar 10y agoI love react, with the reusable components and the ergonomic of jsx but I really don't like what redux does to your code: it involves too much magic, you lose the concept of independent components and every change becomes a global one: everybody is notified of the inner state of each component … To me it just break all encapsulation and just lead to massive tangled code that is really hard to maintain … Edit: I want to clarify what I mean with the «too much magic» part. It's not redux itself which has too much magic in it, just your application flow that becomes magic when using redux, especially with libraries like the one showed by this article or redux-form[1]. [1]: http://redux-form.com/ http://redux-form.com/
- jowiar 10y ago"Too much magic" is a serious stretch. Running through the tutorial here: https://egghead.io/courses/getting-started-with-redux https://egghead.io/courses/getting-started-with-redux, you pretty much reimplement the whole thing. It's just not that much code. There's plenty of optimizations and edge-case handling in the production version, but overall there just isn't much. > you lose the concept of independent components How? Components take props. They're just as independent as they were previously. > everybody is notified of the inner state of each component This... isn't the case. Redux (and Flux in general) is useful when there is application-level data that needs to be shared across different components, and otherwise something ends up being a prop to a bunch of things that shouldn't be. Or when you want something to remain around when components go out of scope. If you don't have this problem, Redux is overkill. For larger apps, it's damn useful.
- stymaar 10y agoIt's not redux itself which has too much magic in it, just your application flow that becomes magic when using redux. > How? Components take props. They're just as independent as they were previously. But in raw react it's straitforward: props are properties passed in the jsx tag of the element. With redux your props just pop out of nowhere when some event is dispatched somewhere in your code and your (smart) component can also change any other component's state without you knowing it. I know this kind of behavior can be useful sometimes (because you exactly want to do that) but in many situation you don't need it (in the same app I mean). My problem with redux is that it makes the remote control implicit instead of explicit. Plus you don't always control redux by yourself but are also encouraged to use a lot of librairies that tamper the global state behind your back: redux-router, redux-form, etc.
- jowiar 10y agoThe caveat here is that with flux/redux, I'd argue "make as few components as reasonably possible interact with redux" is a best practice. If "things popping out of nowhere" is a problem, you probably have too many components listening on your stores.
- acemarke 10y agoThat was actually the early advice for how to use Redux, but experience has shown that leads to less than optimal performance. In fact, benchmarks show that _more_ connected components usually leads to better perf, as the cost of notifying more subscribers is less than the cost of more wasted re-renders. See the following links for more info: - http://blog.isquaredsoftware.com/2017/01/practical-redux-part-6-connected-lists-forms-and-performance/ http://blog.isquaredsoftware.com/2017/01/practical-redux-par... - http://redux.js.org/docs/faq/Performance.html#performance-scaling http://redux.js.org/docs/faq/Performance.html#performance-sc... - http://somebody32.github.io/high-performance-redux/ http://somebody32.github.io/high-performance-redux/
- dvcc 10y agoI don't think its really all that magical when looked at as a giant component. In the context of the react-redux lib, its really similar to just having one large top level component that contains your entire state and all methods you would want to commit (but instead its called a store and actions). Everything is still unidirectional in that it has to go through that main redux provider and then gets passed back down to all the children, without the need to pass around every single possible method to each child. So even if you have two "smart" components they are still just children of that main redux provider and therefore it makes sense that they can impact each other. The same way children can call methods that change a parents state on normal react components.
- d0100 10y agoDepends on how you use it. I just keep my application state in redux. Redux itself has absolutely no magic. The only "magic" I see is when you add state diffing and memoization (reselect). And even in this case, it's not really hard to understand what's happening. React with redux is just a big pubsub system, how you set up your application state and how each component interacts with that state will decide how "tangled" and hard to maintain your code is.
- elliotec 10y agoReselect is super opaque. Very difficult to understand what is happening with reselect from my experience. Agree with all your other points though.
- gtf21 10y agoI really don't think this is true. Redux is simple, and by using the react bindings, you get perfect encapsulation: components take props which can be from the state (so your component needs no knowledge of the state store) or action creators (which makes for easy test mocking). If anything, this makes your components a lot easier to read and reason about (and test).
- bradmwalker 10y agoRedux uses Event Sourcing. ES's trade-offs apply.
- karmajunkie 10y agoIts evented, not normally event-sourced. I don't know of many production uses of redux that also store the events for replay.
- weq 10y agoAddtionally; Why apply your event to the state, then somehow sync your state with the server. Wouldnt it be simplier just to sync your events?
- karmajunkie 10y agoYeah, its simpler, I just don't see many applications doing it. Additionally, not all events need to be synced, some need to be enriched before being synced... by the time you've done all that, you're almost back to syncing state. Which is probably why we don't see many apps doing this with redux. Redux is much more closely aligned with CQRS principles than ES.
- weq 10y agoRedux in its essensce encourages half assed event sourcing. Why do i need to memoise my state to stop the react render loop from happening? Isnt my event the source of truth? Its much more then a DTO. Once your application becomes "event centric" instead of "state centric" you start to actually break free of the procedural paradgim and really become functional reactive. Redux to me is DDD and ES for non-programmers. My domain logic is the gatekeeper to my state, and as such, should be coupled together. I dont combine my aggregates, just the same way i dont combineReducers. Code smell much.
- amk_ 10y agoAn app really becomes an app instead of a view layer for a CRUD API once you start adding in business logic, permissions, unstable networks, etc. I'd love to see a Redux example app that handles those things as cleanly as it handles simple cases.
- ryanashcraft 10y agoGlobal state vs. local state is a problem with several tradeoffs that I don't think anyone has nailed. You might be interested in the discussions and solutions people are developing here: https://github.com/slorber/scalable-frontend-with-elm-or-redux https://github.com/slorber/scalable-frontend-with-elm-or-red...
- stymaar 10y agoThanks !
- shados 10y agoThe beauty of redux itself is the lack of magic. It's essentially just a design pattern and is trivial to follow. So the "edit" part of your comment is key here: frameworks built on top of redux, including middlewares, store enhancers and stuff can definitely lead to an app that is hard to reason about with side effects happening in places you don't expect. IMO that ends up being the worse of both world: even with all that tooling, Redux is far from terse (in favor of being explicit), but you also get the drawback of a deeply layered framework. This isn't worth it. There are other frameworks and tools that do this better. If you want to be terse, and don't mind throwing in a lot of layers on top of your code to achieve it, use one of the countless other (mainstream!) solutions to do so. Redux really excel at "putting the code in your face", giving you easy to follow logic where very little is abstracted (and when it's abstracted, it's just via simple function composition). And at doing that, it is amazing and is my pattern of choice. At anything that diverge from that though, it is so bad it's not funny. Right tool for the right job :)
- limscoder 10y agoRedux is difficult to reason about because side-effects can be triggered from anywhere in the application by middleware. If you're using something like redux-thunk, a single dispatch can cause both a store mutation AND trigger a side effect, which is confusing. I'd rather have those be 2 separate concerns. Those dispatches can be triggered from anywhere in the app, and multiple middlewares may trigger multiple side-effects in new and exciting ways. I find that logic to be difficult to follow and test. I wish it had a more opinionated way to do side-effects, but the solutions like redux-saga seem even more complicated and confusing.
- shados 10y agoyup. Its like i said: redux is simple. Middlewares are what makes it complicated. Redux-loop had a nice model for side effects, but the syntax did not mesh well with javascript limitations. Redux-saga is nice for testing, but it adds new non-standard concepts on top of generators that make it complicated. I really like the Netflix solution (redux-observable). Since JS is not Haskell, side effects can be shoved to the side a bit, but there aren't a whole lot of ways to make them nice. CycleJS probably has one of the better systems. In Redux, even without redux-observables, if you closely follow redux semantics I find that reasoning around thunks works quite well (if you're making sure that your actions are semantic and not glorified setters)
- caioariede 10y agoThe thing I don't like in Redux is all the boilerplate code required to make simple things. I understand that in some point you may want/need to switch over to Redux but to start some projects I'm always considering a simple Event Emitter like node-events.
- acemarke 10y agoObligatory link: Dan Abramov's article on "You Might Not Need Redux", discussing the tradeoffs involved in Redux: https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367 https://medium.com/@dan_abramov/you-might-not-need-redux-be4... . Also, Dan has pointed out that the Redux docs were written in a deliberately verbose style to illustrate what's going on, and people sorta followed that. There's plenty of ways to reduce the boilerplate, and you're welcome to do that as much as you want.
- inglor 10y agoConsider MobX, it's just getter-setter pairs for actual change detection. It's the declarative reactive one-way flow binder you want. It saved me a lot of time. People think redux is about functional immutable stuff. It's not functional and state is obviously not immutable (then nothing would happen). Redux is just about "what's the smallest thing we can do to get React to know when to render" and the answer is "put everything in one function". It's a great educational tool but I don't get why people build big things with it.
- stymaar 10y agoThanks, I'll have a look at it. Edit: The first result for MobX in the French version of DDG is a porn site xD.
- ykler 10y agoRedux Form really goes against the spirit of Redux in my opinion. It uses Redux internally, but you can't really directly access the reducer it uses, so from the user's perspective it is almost like it's not using Redux. The one serious library choice mistake I made in my first React/Redux app was using Redux Form. It was almost impossible to do things if the library hadn't anticipated my exact use case. I ended up having to rip out a bunch of code, and I switched to React Redux Form[1] even though it was a very immature library at the time. [1]: https://github.com/davidkpiano/react-redux-form https://github.com/davidkpiano/react-redux-form
- allover 10y agoHonest question, what is the reason for using a global store for form validation? That seems like the ideal use-case for local component state.
- ykler 10y agoIn my case, I had an editor for a structured document where the user could modify some parts of the document using a form and others using other components, some of which used forms internally. I wanted to have the whole document represented as an object in my Redux store that was also synced to the server.
- allover 10y agoGotcha, thanks! Seems a shame that Redux-Form (and similar) are presented for more trivial solutions than yours. I don't see many forms that also need modification via 'other components', in a way in which that state can't just be handled by a sensible parent component.
- whiskypeters 10y agothis is the first time i've ever heard someone complain of redux having too much magic most people complain there is too much boilerplate!
- tonyhb 10y agoHeh, I made the same thing but with global endpoints and swappable drivers so that components can be shared and endpoints can be stubbed/mocked: https://gitHub.com/tonyhb/tectonic https://gitHub.com/tonyhb/tectonic Think that genraally we're learning that these things should be automated for us: loading data traditionally sucks. GraphQL is really where it's at! edit: that mobile keyboard though...
- djmashko2 10y agoYeah, Apollo Client helps you do a lot of these kinds of things with GraphQL - deduplicating requests, keeping track of loading states, etc: dev.apollodata.com (disclaimer: I work on Apollo)
- ryanashcraft 10y agoAuthor here. I totally agree if you're starting a new project or have the bandwidth to migrate to GraphQL – definitely consider it! However, I still think we'll need solutions that work for apps that use non-GraphQL APIs.
- gtf21 10y agoI've been having this discussion both in my own head and with my team for the last couple of weeks and have been thinking about how to implement something like this (but haven't got around to it). Looks great!
- netghost 10y agoThis looks like a really great library for simplifying API interactions. I'm curious though if there's any way to indicate that a component depends on more than one end point. Would you just wrap it in multiple `connectRequest` wrappers?
- ryanashcraft 10y agoAuthor here. Thanks! That's what we do. It's an OK workaround but ideally `connectRequest` would support multiple queries. Another workaround is to manually dispatch `requestAsync` actions, which might be necessary if you need to chain the requests.
- HorizonXP 10y agoWe were just about to start migrating to GraphQL and Apollo, so this definitely came out at the right time. Our issue is that our API is nested, and does require many nested requests. This would probably be the best solution for us though. Unfortunately, I don't see anything related to server-side rendering?
- ryanashcraft 10y agoYeah server-side rendering hasn't been a focus for us. Currently, I don't think it is a great solution for server-side-rendered apps. I'm not exactly sure how much it would take to improve things here. If you have any thoughts around multiple requests or server-side rendering feel free to submit an issue on Github to discuss! https://github.com/amplitude/redux-query/issues https://github.com/amplitude/redux-query/issues
- limscoder 10y agoDoes it de-dupe requests if multiple components need the same URL?
- arbesfeld 10y agoThis is really cool! We have been using react-refetch from Heroku [1] for a similar purpose and it will be nice to have all our state in Redux. Another perk is that LogRocket [2] will capture this data now :) [1] https://github.com/heroku/react-refetch https://github.com/heroku/react-refetch [2] https://logrocket.com/ https://logrocket.com/
- limscoder 10y agoI've been experimenting with using a component to fetch data. The data to fetch is declaratively described as props. https://github.com/limscoder/react-wrangler https://github.com/limscoder/react-wrangler It uses immutable and allows for time travel debugging.
- netghost 10y agoThat's a really neat approach. I like how it allows you to trigger code on missing paths. That seems like a really simple way to model an API.
- sktrdie 10y agoI don't understand how this solution differs from actual side-effects managing libraries such as redux-saga or redux-cycles. Network requests are certainly side-effects and putting all their logic together with your Container code seems like a code-smell.
- acemarke 10y agoIf anyone's interested, I maintain a list of Redux-related addons and utilities over at https://github.com/markerikson/redux-ecosystem-links https://github.com/markerikson/redux-ecosystem-links . Includes just about every vaguely-useful-looking middleware, action-generation utility, devtool, store enhancer, fill-in-category-here, that I've seen out there. (And yes, I already had redux-query in the list before this post :) )
- ryanashcraft 10y agoAwesome resource! And thanks!
- acemarke 10y agoSure. I'll also throw in a pointer to my React/Redux links list, which contains links to high-quality tutorials, articles, and other resources for React, Redux, ES6, Webpack , and related topics. Specifically intended to be a great starting point for anyone trying to learn the ecosystem, as well as a source of solid info on more advanced topics: https://github.com/markerikson/react-redux-links https://github.com/markerikson/react-redux-links
- deevus 10y agoI went to star this only to realise that I already had Great work :)
- mpolichette 10y agoThis is cool, I was looking a library which would help me with CRUD and paging data recently and there weren't a lot of great options. So I started working on a library which ended up looking kind of similar to this. One of the goals I've had is to stay encapsulated and not force any decision on the developer for the request library like redux-query does. I also try to avoid touching their data. It isn't quite flushed out all the way, and needs more test, but I've started using it and enjoyed the way it works. I'd love any feedback if anyone wanted to check it out, https://github.com/SpinGo/crudux https://github.com/SpinGo/crudux
- Rodeoclash 10y agoI'm very surprised that Relay is not getting more traction in this space. Given, it's a lot of work to get it set up and running but once it's in place it's great. I haven't found a library that manages network state and the associated difficulties that come with it better. No reason why you cannot combine both Redux + Relay, in fact once the app gets to a certain size and you want to rely less on passing around long chains of callbacks and state objects then you pretty much have to implement either Redux, Mobx or similar.
- netghost 10y agoSo relay assumes you have a graphql backend, which is a tall order for a lot of existing applications. If I was building something from scratch, I'd be tempted to try that approach though.
- djmashko2 10y agoWe built a new GraphQL client that makes it especially easy to integrate with Redux, which also handles all of the related concerns about data caching and state management: http://dev.apollodata.com/ http://dev.apollodata.com/
- ex3ndr 10y agoNice component, we are working internally on something same, but for Kotlin.Js + React (nothing to show yet), but i have one question: How to solve a problem when same entities have different fields, for example: List of members of a chat should display avatar, name and username, but viewing profile usually use much much more data to display. How to merge them? How to keep fields in sync and not to download everything in all requests. For example, loading all members can be slow when fetching full user profiles and should be avoided.
- weq 10y agoEveryone says redux and react make for great component isolation. How many of you people who use this combo can swap redux out at a whim, for another state management tool? How many of your components have been modified to work with the opinions of redux? Why do i need to couple my components with redux using connect()? In my experience, redux and react on there own present decent patterns to simplify UI experience, but ive never seen a discussion that involves them that doesnt couple one with the other.
- nikcub 10y agoThere are two ways to make them more loosely coupled: 1. declare your connect's in a separate file that import your component and live alongside your containers, actions, reducers, etc. 2. write your own connect HOC that brings in redux. If you read the connect source[0] you'll find that it is actually really simple at it's core - but it is over complicated by having to account for so many use cases - your own HOC could/should be ~30 lines I now use 2. because it produces proper separation and makes it easy to swap out components later on (or use more than one). [0] https://github.com/reactjs/react-redux/blob/master/src/connect/connect.js https://github.com/reactjs/react-redux/blob/master/src/conne...
- mlsarecmg 10y agoSwapping the management would be difficult, they all have their own patterns and implementations. But swapping Redux is absolutely possible. The logic sits in a self contained container which you can plug into literally every framework under the sun. The "connect" you're talking about is in place for React, Ember, Angular, Vue, Knockout, Mithril, Cycle, etc. Redux is also the closest you can get to a true universal app, because you can share it between code-bases (desktop app, web app, mobile app, backend even if you need). We deploy a library based on this. It has reactive/changing datastructures that need to be presented visually. It runs on redux internally, and that is what makes it possible for our customers to embed it, no matter which framework they choose, even if it's JQuery. They form a simple dress and get served the properties and actions to display and excute. "Connect" makes their stuff aware of changes.
- TheAceOfHearts 10y agoWe try to keep our views and business logic reasonably well isolated. You see something in larger REST APIs, where the business logic is wrapped in a service object with is kept separate from everything else. Recently we had a small "hackathon" event to evaluate GraphQL and Relay. Once the GraphQL server was up and running, getting Relay working with our app was really easy. Unfortunately, the migration path for adopting it heavily didn't seem to be worth it for us.
- cel1ne 10y agoI managed network state using react in the DOM itself, using hidden divs with custom onDidMount, onWillUnmount hooks. Worked really well.