I am using redux-form 7.2.0.
In my Project , I have 30 Fields in my form.
Based on the First Field Value , i need to update some 20 fields. i call change action creator for 20 times. it takes more time to render these 20 fields. very slow.
is there any way to make it fast in render?
or
is there any way to update multiple fields in single action?
please help me to rectify this
Really the only correct answer is to use an additional middleware provider. See dispatch multiple actions from Redux action creators to get an idea of the pros and cons.
You could set a flag somewhere in your state tree when the first field changes, avoid rendering via shouldComponentUpdate until all fields have been updated, then when everything has been updated, set that flag back.
The only other way I could think about handling this would be using the reducer.plugin to make a larger state change, but I think this is a dangerous path that could easily break in the future and just not behave in a predictable manner.
Currently batch field changing is not supported by redux-form or redux directly.
Just use initialize action provided by redux form.
There are two ways to use this:
https://redux-form.com/7.4.2/examples/initializefromstate/ Initialize it when creating a form, like they did in the example.
Pass 'initialize' action as prop and call to update all the fields with one action call.
const data = { firstName: 'John', lastName: 'Doe'};
this.props.initialize(data);
Just make sure to match the field names with keys in data object.
This will fire one action and all fields will be initialized.
Related
I have seen many times people are connecting redux to component and they are using second parameter in mapStateToProps.
function mapStateToProps(state, ownProps) {
return {
rowData: state.table.rows[0],
};
}
Is in it useless? If child component has passed props from parent why should we map/pass them again in mapStateToProps?
What is the advantage of this?
Greetings
The usage of second parameter in mapStateToProps depends purely on the application. Mostly you may not need it, but in certain scenarios where the selector depends on the props to filter out the result, it is useful to use the props value from mapStateToProps
A scenario where your might need to make use of props are
Say you have a redux state data called used and you only need to show users in a specific region that comes as a prop to the component. You can make use of this prop value in mapStateToProps and return the filtered results instead of returning the entire result and filtering in render which might be a little less performant
You can avoid unnecessary renders, via retaining some possibly small subset of the store data with the help of some props.
For example, you have a slideshow application and Redux stores all the slides, and your component is responsible for a single slide. A prop value contains the slide number. By extracting the store data only for that specific slide, you make it easier for React and React-Redux to avoid unnecessary rerenders. Maybe the store changed due to some other user having edited another slide, in your collaborative presentation editor - no reason for your slide to get rerendered.
https://react-redux.js.org/api/connect#ownprops
Besides, Redux is global state, while your component can work with data just needed for that component. If you have plans to ever reuse your component, OR to ever consider switching from Redux (or even React) to something else, or just want to follow good practice by uncoupling Model from View, then it makes sense to separate your component from what's essentially a singleton global variable as much as you can. By carving out only the data you need, and possibly shaping it to the needs of your component, you performed a global Model to local ViewModel mapping, and it's easy to take your component elsewhere, without concern for what the global Model was when you implemented it. By using eg. Recompose, you can take it further and make things you can just move around freely.
There may overwrite the previous field, so it gives you a choice.
eg: return Object.assign({},state,ownProps);
The second arguments normally comes into picture when you want to extract the some values from the props or assign value in the return of mapStateToProps using your values in props, then the second argument comes into picture. A classic usage would be writing selectors which uses values from store and the props passed to the component.
This is a bit complicated so I'll try to put it as simple as possible.
I have a pretty much complicated reusable component in my app.
Basically, it is a large table with many editing options.
Since this component should be reusable, my thought was that it should manage it's own state.
It also makes sense because this component's business logic is pretty much complicated, and by using redux, I'll probably have to repeat some crazy boilerplates.
On the other hand, this component should be able to have some default data loaded to, and finally, this component is in some cases a part of a form, so I sohuld be able to extract it's data and send it to the server.
Redux can really help with the last two tasks - if I had an easy way to store all component changes in the store, I could easily load the default data from there (because my component will be fully controlled), and it will also be easy to extract data from the store when sending to server.
Although, it has a lot of boilerplate, and I'm not feelinng comforotable to write a componenet specific logic in my reducers, since ideally, they could manage themselves.
Any more ideas about that?
I had one idea that seems to be working, though I am not sure how good it is:
Have a "dataKey" prop to handle default data prop changes, and derive the state from the data
Use some submit callback to extract the data and send to server
Any more thoughts will be very helpful, thakns!
It's hard to provide an extract answer as your question is kind of abstract. But since you are just looking for ideas, this is just an idea which you can try to incorporate with the actual use case.
In this kind of scenario, I would first distinguish my actual data and UI state. Then I will write my component as a controlled component of actual data with the usual value and onChange props. The UI state will be kept in the internal state of the component and it will either be derived from the initial props or initialized with a default value. When the user interacts with the component, if the change affects only the internal state, we can just use setState to update the state. If it affects data also, we can fire onChange prop also accordingly. This way we can keep the actual data in the redux store, but still, keep component specific logic in the component.
As an example, let's say we want to make a text label component with in-line/in-place editing support. I would still keep the props of this component similar to the default HTML input element as value and onChange. But the flag that indicates whether to render a text or input element with 'Submit' and 'Cancel' buttons will be kept in the component as isEditMode. Initially, we can always keep isEditMode as false. But when the user clicks on the text, we change it to true, so that component will render elements for editing and hide the label. While the user changes the text we can keep that intermediate value also in UI state. But when the user clicks the 'Submit', we can fire onChange with the new value in state and change isEditMode also to false. Likewise, we can keep the component as a control component but still use the component state to manage intermediate UI states.
Hope this helps!
I am new on react. I am working on react application with redux. I have a form (I am using redux-form) by which I can save data or edit data.
my problem is , In edit mode I populate data using componentWillReceiveProps. and populated perfectly, now when I try to clear any field on form its again fill.
componentWillReceiveProps(nextProps){
this.props.dispatch(initialize('NewProject', nextProps.project.project[0]));
}
I would be grateful for any help.
Is there a reason you're not dispatching this action somewhere else, like in componentDidMount? I can't say without seeing more code, but it's possible that whenever you edit your form, React again calls componentWillReceiveProps and overwrites whatever you did with the behavior you've given your component.
Per the React documentation:
Note that React may call this method even if the props have not changed, so make sure to compare the current and next values if you only want to handle changes. This may occur when the parent component causes your component to re-render.
It may be a good idea for you to move your dispatch to a more predictable event if possible, like componentDidMount. Typically, your render method should be capable of handling different cases if a component has multiple possible states. You could also create an edit and save version of your component, and render one or the other based on the props you receive. The best way to "populate" data, as you put it, is to define propTypes for your component, and then use your props to insert that data into elements in the render method.
Looking for some advice when working with Redux, and Angular. I've been researching Redux for the past couple of days and really think its a great way to store application data. The part I'm having trouble with is whether to persist everything within the store or only certain parts. Ideally, I think the entire application should be running through the store, but for forms this seems very tedious.
For example, lets say I'm working with a form to add a new product. Here are some of my pain points.
I would like to keep the User Reducer (store) separated from the actual form state. Should I create a separate form reducer per component?
Having to persist every input field back to the store sounds like a lot of work. I've seen the library redux-form simplifies this, but is intended for React.
Anyone have any good advice when it comes to creating forms in Angular with Redux?
The answer is "it depends". Also, the assumption is that you''re convinced of the benefits of one-way data flow and redux, so prefer redux over two-way data binding if given the choice.
Uber-simple form (no validation, no complex relationships with other state). Then you could "go naked" and directly hook up the inputs to redux. In our use case, we actually decided to go with Angular forms because we figured it handles edge cases (IE and safari mobile).
Don't need every form change in redux state. Then the form submit can dispatch an action to update redux state. Things get tricky if the form needs to change in response to redux state. See below.
You do need every form change in redux state. Angular forms do not have a form#ng-change, so one strategy is to attach an ng-change to every input that dispatches an action to update the redux state. (Yes, it is error prone because it easy to forget to use ng-change, meanwhile the app appears to work.) Again, things get tricky if the form needs to change in response to redux state. See below.
Updating the form in response to redux state change
The common use case is actually very simple. A concrete example will help---suppose the form tracks app settings, meanwhile app settings exist as redux state. That is, there is a two-way data binding between the Angular form and the redux state. This is probably the common use case.
In this case, the solution is to proceed as before: update redux state from the Angular form by dispatching update actions, and update the Angular form from redux state via #mapStateToThis.
Angular ----dispatch actions-----> Redux
Form <----mapStateToThis-------- State
The only gotcha is to not pass the Redux state directly to the Angular form i.e., deep clone the data or use ImmutableJS.
The other common use case is to implement a "form reset", that is, reset the form to a "pristine" state after pressing a button, for example. Again, a concrete example will help:
Suppose that app state (redux state) tracks whether the state is pristine via a flag app.pristine. (To clarify how app.pristine works, it works as expected, that is, it changes to false as soon as any value changes, and changes to true only when explicitly set to true.)
First, as far as I know, Angular doesn't automagically keep track of the "initial" state. You have to do it yourself and you may as well put that state in redux. Then, the initial form values are just the app settings when app.pristine is false. (If you're thinking of putting this in #mapStateToThis, don't. Doing side effects in a transform function seems weird.) A better way is to use an asynchronous action, namely the form onChange listener:
// thunk example
onFormChange(newForm) {
return (dispatch, getState) => {
const appSettings = getState().appSettings;
const appIsPristine = appSettings.pristine;
// this will fire once because the next action will set it to false
appIsPristine && dispatch(initForm(appSettings)));
dispatch(updateAppSettings(newForm));
};
},
The reset action works as you would expect (which I won't outline).
To conclude, I should add that the above assumes that only the Angular form can dirty the app settings---otherwise, the initial form values may never be stored. If that's the case, then one idiomatic solution is to create a custom middleware that sets the initial form value whenever app.pristine changes to true. (Alternatively, use an Angular watch.)
My current reactjs/flux implementation is to have components call actions, and actions call the web api which then funnels back to the store.
I have a set of checkboxes where the state of the checkboxes are managed in a store, but every time I update the checkboxes, I would like to make a query to the server with the state of the store. What I am forced to do now is call an action to update checkboxes store when the checkboxes are clicked, in the checkboxes store, set a variable to "queryServer", then in the checkboxes component, check the "queryServer" and make another action to query the server.
It seems simpler if both components and stores can make action calls, that way, when I update the checkboxes store, I can initiate the action to query the server directly without setting a silly "queryServer" variable and having the component check that.
Though it does seem to make things simpler, it seems to go agains the essence of the flux architecture where all actions are initiated from the view.
My approach would be to fetch the state of the store into the view and pass it to an action from there. This would allow your store to stay as dumb as possible, simply receiving data as it comes into the application.
In more specific terms, your store would have a getData function that returns the raw data stored. In your component the click handler for your checkboxes would include code looking something like this:
var data = MyStore.getData();
MyActions.queryServer(data);
Your action would then make the API call (since it's probably the safest place to do anything asynchronous) and pass the new data to your store via the dispatcher.