4 ms·
The surface area of react and redux is small and simple, but that doesn't mean that building complex applications with it is easy. Essentially, redux is just a
by d0m 10y ago
The surface area of react and redux is small and simple, but that doesn't mean that building complex applications with it is easy. Essentially, redux is just a big reduce on an immutable object. The just here is what makes redux great and open many possibilities with the time travel, etc.
That being said, I'm still trying to figure out how to build a few parts of my app the "Redux" way and I feel like it's making it way more complex instead of simplifying it.
For instance, in most redux trivial examples, the store and the views are directly mapped. I.e. 4 tasks in the store = 4 tasks on the screen. But in practice, sometimes the view evolves differently. Maybe we don't want to show the new task because it would confuse the user and it would be better instead to show a "Show new changes" button.
But then, you're now duplicating the state of the app. Since redux only tells you when the AppState has changed, how do you figure out how to update that UIView strictly from the AppState()? Yes, you can regenerate UIState every time but you need to store additional stuff in the AppState to be able to do that (For instance, was the "Show Change" button shown or not?). Also, regenerating a very big object on every change in the store can truly degrade performances.
There are some libraries (Such as reselect), but it's essentially the same thing, your view object needs to be recreated from scratch when there's a relevant change in the AppState.
One possible solution is to have components listen to the store actions and they would have their own reducer to update the "UIState" accordingly. But then it's moving away from the current "Redux Way".
That's just one example of how it can get complex even though the redux idea (One store, one reducer) is simple.
By the way, anyone knows how to solve the issue I just mentioned? :)
- acgourley 10y agoThis performance tip seems relevant to you: https://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate https://facebook.github.io/react/docs/component-specs.html#u...
- d0m 10y agoI'm already using immutable objects, this is a separate issue. The question is about how to keep the UIState (Say inside a component) in sync with the AppState considering they both evolve differently?
- acgourley 10y agoThe official Redux answer way is to use app state for everything. See libraries like https://github.com/erikras/redux-form https://github.com/erikras/redux-form which move all the field state into your app state. Personally I break that rule when I know I can. The only other state I can think of is animation state - but using css transition animations has just worked out for me so far.
- acemarke 10y agoActually, no, it's not. In fact, the Redux FAQ flat-out says "It's up to you to decide what state goes where": http://redux.js.org/docs/FAQ.html#organizing-state-only-redux-state http://redux.js.org/docs/FAQ.html#organizing-state-only-redu.... There's certainly some good reasons to put as much of your UI/app state into Redux as possible, but there's also entirely valid reasons why you might not want to put some state in there.
- acemarke 10y agoA few thoughts: * For the "Show new changes" case, what you might do is maintain an object that does id->item storage of tasks, then have separate arrays of "task IDs being shown" and "task IDs that are new". The task list only cares about the "being shown" values, and in mapStateToProps, could show the "Show new changes" button if the "new tasks" size is > 0. * You can also add additional logic in your mapStateToProps, or your component's componentWillReceiveProps functions to see how things might be changing. * Per-component state in the Redux store is a topic of open exploration. I also have a list of Redux-related libraries over at https://github.com/markerikson/redux-ecosystem-links https://github.com/markerikson/redux-ecosystem-links , and the "Component State" category lists at least a dozen libs that can dynamically put per-component data into Redux. That said, it's also entirely valid to keep data in your UI component's state as well - it's up to you. Finally, if you're doing shallow-cloning and proper immutable updates to your state, that process shouldn't generally be a performance concern. Also, React Redux does a _lot_ of work to make sure that your wrapped component only updates when it absolutely has to.
- cel1ne 10y agoI decouple my UI state and my appstate like described here: https://medium.com/@spitzwegerich/a-different-way-of-supplying-react-components-with-state-1093f8f79802 https://medium.com/@spitzwegerich/a-different-way-of-supplyi...
- grayrest 10y ago> Maybe we don't want to show the new task because it would confuse the user and it would be better instead to show a "Show new changes" button. For the past year at work I've been working with re-frame (clojurescript) which has roughly the same model. The main difference is on the reducer side: components dispatch an event vector directly with the event keyword (action) as first element, then instead of a reducer that switches on action strings, we register a set of event handlers that take a map that looks like the app state and event vector and return an updated version with the reduce happening in the framework. It's really close. The main advantage is that the event handlers are functionally pure and we can apply middleware functions to the handlers on a per-event basis, which we use for analytics, state coordination, input validation, chained event triggering, etc. In the same controller namespace where we're registering event handlers, we also register topics. A topic is a registered reactive computation like a spreadsheet cell. I'm sure people have built the abstraction for Redux. We'd have `tasks` and `last-displayed-task` in the app state and register `displayed-tasks` (drop-while #(not= @last-displayed-task %) @tasks) and `new-tasks?` (not= @tasks @displayed-tasks) then have the task-list component pull out of `displayed-tasks` and the button show/hide with `new-tasks?`.