Flux documentation states that state should be stored in Stores. Should then the loading, saving, error messages related a entity be stored in Stores. Since View is going to get its initial State from Store hence only way to know whether its loading/saving comes from a Store.
Also when editing a form user decides to cancel editing hence these intermediate form values should be stored in Views states rather then sent to Store?
I use React in a very functional way, as all my data is stored outside of React as a global JSON object, and that data is injected to a top-level component. Thus React is just a clever templating engine for me: a transformation of JSON to Virtual DOM, and then application of Virtual DOM to the real DOM. Rendering always trigger from the main component and is optimized thanks to immutability. Read more here
I don't agree with Rygu, the errors are part of the state. Stores may be comparable to databases, but what does that mean? That stores should only contain something that is not "temporary" or something that may be considered as meaningless?
For me, if you want to embrace functional programming with React, anything that is displayed as DOM should rather be in the first place passed as props of your components, including errors. If you don't, then you rely on side effects to manage the DOM, and it will be harder to reason about all these side effects over time.
Your input fields should have their own memory. That means that Store state (source of truth) is immutably decoupled from any changes that happen in components. Through actions, those changes are communicated to the Stores. Whether they become the new truth or fail with errors, the Store state will again be immutably copied to the component input state. Errors, I would also move to the component as they apply to the input state, not the Stored state.
Stores are like databases, you rarely put any temporary records or errors there either. Unless you're writing a text editor where input history is tracked...
Related
In my application I have a dialog window on which there are multiple input fields. What I want to do is to save user's input in the component's own state and only afterwards, say, inside "onClose" of the Dialog send the input to a redux store using "dispatch" function.
This way the dialog component would keep field data inside its own state.
The problem that I face is that I'm not sure what the best way is to rebuild dialog component state from information contained in the redux store.
If one refreshes the page with F5 or simply reloads it, then components lose their state and fields will appear blank, regardless of the fact that rehydrated redux store still contains valid input information.
The question is then, what is the best way to set components state from props? Moreover, doesn't it seem like an antipattern? What are some common techniques for such task?
One possibility is to set field values directly to those contained in "props". This would, however, imply that every small change of the input fields will result in copying and modifying redux store, which is slow & inefficient.
Usually building a state from props complicates code a lot, you have to map props both in constructor and getDerivedStatesFromProps.
I prefer to write component functions which return value based on passed props.
As you mentioned it may impact perfomance, to fix it you can use memoize-one library.
For more details you can check the following answer
I'm pretty new to Redux and would like to use it my application but I'm stuck at architecture/design phase for the Redux part. Here are my requirements and my suppositions regarding the design.
Application details:
SPA with AngularJS. Other libs used ng-redux, reselect, rxjs.
Component details:
Re-usable grid component to render huge amounts of data.
My idea:
Create a plug-n-play kind of component-based architecture, where all the internal components of the grid are independent of the parent/composing component like search, sort, row, header, cell.
All the components will have their own set of reducer, action, selector, and slice of state from the store.
Because all the components have their own reducers and can be plugged-in on demand, I need them to be lazily registered to the store instead of being accumulated in one place.
Some of the components like search, sort along with having their own state, also can affect other components state. Ex: setting up of query parameters (searchText, sortOrder etc.) to fetch the grid data which would be handled by another component(s).
My thoughts:
For the 1st point, I'm looking into reselect for supplying the dependent slice of state.
For the 2nd point, I'm still confused about which to use combineReducers/replaceReducer for the lazy registration. I feel combineReducers will not fit if I want access to multiple parts of the state.
For the 3rd point, I'm thinking of following approaches:
a. Passing entire state via getState() wherever required to update multiple parts of the state. Though this approach gives me feeling of improper use of Redux.
b. Component A fires its own action which updates their part of the state, then another action is fired for the other component B to update its slice of state. This approach as well feels like breaking the whole idea of Redux, the concept of side-effect could be used here though I don't know how to use it, maybe redux-saga, redux-thunk etc.
NOTE: Use of either of the approaches shouldn't lead to the component knowing about the other components hence whatever has to be done will be done by passing a generic config object like { actionsToFire: ['UPDATE_B'] }.
I need state management while navigating back and forth between the pages of the application, but I don't require hot-reloading, action-replay, or pre-fetching application state from server-side.
Components will also be responsible to destroy their state when no longer required. And state will have a normalized structure.
I know the requirements might seem weird or not-seen-often but I would keep them that way.
Few things I already know are:
I don't need to use Redux like the classic article from Dan says, but I think I need it here in this case.
I know about the Smart and Dumb components, mostly my components might seem smart (i.e aware of application state) but that is how I want to keep them, I might be wrong.
Diagram of the grid component:
Grid Component Diagram
Redux's global store makes encapsulation and dynamic plug-and-play behavior more difficult, but it is possible. There's actually many existing libraries for per-component-instance state and dynamic registration of reducers. (That said, the libraries I've seen thus far for component management are React libraries - you'd have to study some of those and reimplement things yourself for use with Angular.)
I have two components, contact form, and input.
At this moment i pass onChangeEvent from contact to input as is described in many tutorials and its works fine - input update his owner state.
But there is way to pass 'this' from contact to input by prop, or context and then I can update owner state without passing onChangeEvent - but is this a good idea?
Is there another option to update owner state without passing onChangeEvent?
I believe you could technically do it, as a React component is a regular javascript object in the end, so you could pass it as a prop.
However, that's not a good idea in general, for various reasons:
It tightly couples the two components together. If you ever want to reuse the input component in another place, you'll need to pass in the exact same state.
Linked to this, it allows manipulation of the internal state of one component, by another component, which is a violation of good OO design.
You are right however, that things tend to become quite verbose when working like this. They also become hard to reason about when one has more complex trees of components passing props and change handlers between them.
One solution to the problem, is employing the Flux design pattern, and namely it's Redux implementation.
In Redux one has a single piece of global state, a plain object, of which components see pieces (sub objects). Components receive this state as props, and just render from it in a simple fashion. There's a set of actions which transform this state, and any component can issue such an action, as a result of user interaction. There's still the concept of "state", but it is reserved for truly local things, such as the state of a form before pressing the save button etc.
I'm new to Redux - and I'm really trying to get the big picture of using functional programming to make unidirectional data more elegant.
The way I see it- each reducer is taking the old state, creating a new state without mutating the old state and then passing off the new state to the next reducer to do the same.
I get that not causing side effects helps us get the benefits of a unidirectional flow of data.
I just really don't get what is so important about not mutating the old state.
The only thing I can think of is maybe the "Time-Traveling" I've read about because, if you held on to every state, you could perform and "undo".
Question:
Are there other reasons why we don't want to mutate the old state at each step?
Working with immutable data structures can have a positive impact on performance, if done right. In the case of React, performance often is about avoiding unnecessary re-rendering of your app, if the data did not change.
To achieve that, you need to compare the next state of your app with the current state. If the states differ: re-render. Otherwise don't.
To compare states, you need to compare the objects in the state for equality. In plain old JavaScript objects, you would need to deep compare in order to see if any property inside the objects changed.
With immutable objects, you don't need that.
immutableObject1 === immutableObject2
basically does the trick. Or if you are using a lib like Immutable.js Immutable.is(obj1, obj2).
In terms of react, you could use it for the shouldComponentUpdate method, like the popular PureRenderMixin does.
shouldComponentUpdate(nextProps, nextState) {
return nextState !== this.state;
}
This function prevents re-rendering, when the state did not change.
I hope, that contributes to the reasoning behind immutable objects.
The key of the "no-mutations" mantra is that if you can not mutate the object, you are forced to create a new one (with the properties of the original object plus the new ones).
To update the components when an action is dispatched, Redux connector checks if the object is different, not if the properties have changed (which is a lot faster), so:
If you create a new object, Redux will see that the object is not the same, so it will trigger the components updates.
If you mutate the objet that it is already in the store (adding or changing a property, for example) Redux will not see the change, so it will not update the components.
I'm pretty new to Redux (and React.js) too, but this is what I understand from learning this stuff.
There are several reasons why immutable state is chosen over the mutable one.
First of all, mutation tracking is pretty difficult. For example when you are using a variable in several pieces of code and the variable can be modified in each of this places, you need to handle each change and synchronize results of mutation.
This aproach in many cases leads to bidirectional data flows. Pieces of data are flowing up and down across the functions, variables and so on. Code starts beeing polluted by if-else constructions that are oly responsible for handling state changes.
When you add some asynchronous calls your state changes can be even harder to track.
Of course we can subscribe to data events (for example Object.observe), but it can lead to situation that some part of application that missed change stays out of sync with other part of your program.
Immutable state helps you to implement unidirectional data flow that helps you to handle all changes. First of all data flows from top to bottom. That means all changes that were applied to the main model are pushed to the lower components. You can always be sure that the state is the same in all places of the application, because it can be changed only from one place in the code - reducers.
There is also one thing worth of mentioning - you can reuse data in several components. State cannot be changed (a new one can be created), so it's pretty safe to use same piece of data in several places.
You can find more information about pros and cons of mutability (and about the reason why it was chosen as a main approach of Redux) here:
Pros and Cons of using immutability with React.js
React.js Conf 2015 - Immutable Data and React
Immutable Data Structures and JavaScript
Introduction to Immutable.js and Functional Programming Concepts
Why immutable collections?
Redux checks if the old object is the same as the new object by comparing the memory locations of the two objects. If you mutate the old object’s property inside a reducer, the “new state” and the “old state” will both point to the same object and Redux will infer that nothing has changed.
No reasons. The are no any fundamental reasons that shouldComponentUpdate "pure render" optimization can't work with mutable state containers. This library does it, for instance.
https://github.com/Volicon/NestedReact
With immutable data the reference to the data structure itself can be used as version token. Thus, comparing the references you're comparing the versions.
With mutable data you will need to introduce (and compare) separate version tokens, which is hard to do manually but can easily be achieved with smart "observable" objects.
There are several reasons.
Because of the history (undo/redo) feature.
You can use the history feature also for debugging.
Race conditions: Lets say you have a service that logs some state data
after 1s. If you change the state before the service has logged the
data the service will log the wrong data. Of course you could copy
the state before passing it to the service, but it's easy to enforce
this rule if you do it in a mutation/method in one place, the store, the
single source of truth.
seems like I am thinking in the wrong direction.. I have a react app that's using redux. Now I have a reducer that's getting data from a server. For one Component, I need the data to be transformed which I'd like to do within the reducer.
But if I transform the data, it's transformed for all subscribers isn't it?
So is it possible to transform data within a reducer on the fly, but doesn't save the transformed data within the state? (Well this sounds like a dump question..)
Often components will need special data that can be derived from store state, but which isn't store state. As one comment suggests, you can just write a function that does the transformation, and call it from the component. These functions are sometimes called 'selectors', since they select and transform parts of the state. However, this can cause problems, since the value will be re-computed every time any state changes, and since it's derived data, everything depending on it will be re-rendered.
There is a redux extension library that provides a solution to this problem, by allowing you effectively to declare the precise parts of the state that your selector depends on. This means it will only be recomputed when these parts change, avoiding the re-render every time problem. See:
http://rackt.org/redux/docs/recipes/ComputingDerivedData.html
and https://github.com/rackt/reselect
You may choose to completely encapsulate your store state, and have components only ever access the state via selectors. This has the usual encapsulation and related benefits (e.g. insulating your components from some re-factorings to the store state).