React Redux and Input's onChange - reactjs

I'm dealing with many fields on one page, some of them are connected, some of them are not. You can simple imagine it as a Page with fields, or something like this. I know there is two ways of handling the state of the input(storing its value):
storing inside the Redux's store
saving in local state and then dispatch it to the Redux's store on some event(like save button)
I really like the way of Redux and how it handle things and its single source of truth, but the thing is that if I do go with the first approach, I will need to dispatch an action every single time I change a key in input field. Is this me or does it really looks insane? To set a single input, I will need to dispatch around 50-100 times. What if this a longer message, like some post's textarea field?
I thought of throttling or debouncing, but really don't want to make it this way.
Can you please suggest something? Thanks

Related

Initialize state from props using rehydrated Redux store

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

Automatically calling action AFTER redux state is loaded

I have a app in which users can build a "Quote". So far I've been adhering to "idiomatic" redux (or something close to it) and it's been working out well.
However, I'm struggling to deal with a fairly simple scenario:
When the page is first opened, I fire an async LOAD event which retrieves info from the server needed to build the quote (products, inventory, previously saved line items, etc).
I need some way to be able to automatically add a specific line item(s) to the quote first it's first opened.
I've added a defaultLineItems property to my LOAD payload, but to fire the addLineItem(product, inventory, options) action, I need data from the productReducer, inventoryReducer, optionsReducer. The lineItemReducer could look at these defaultLineItems and try to set it's state appropriately, but that would require having to rewrite a lot of BL typically handled by the actions using data aggregated from reducer memorized "selectors" (EG: defaulting price, quantity, currency translation, etc)
I can think of a couple ways to achieve this, but they all seem somewhat hack-ish (IE storing a flag in the reducer that says I need to fire an action and then running it when my root component props update). It seems like a react component should not be responsible for this type thing.
What is the proper way to do something like this?
Seems there are a couple different ways this can be accomplished but for me the most balanced approach between simplicity and design was to use store.subscribe in conjunction with a reducer to track the last action(s).
At it's simplest, this would look something like this.
store.subscribe(function() {
let state = store.getState();
if(state.lastAction.type === ActionKeys.LOAD){
console.log('load action fired!');
}
})
Please be aware that firing an action from store.subscribe will cause recursion so you need to be selective.

Update Redux store for every character entered in a input field?

I have a sequential data collection app built with React and Redux. Right now, I have internal state for each page which has a form and when user clicks "Submit" button, I am dispatching the data collected in the state and updating my Redux store. Should I be dispatching an action on every key entered(debouncing) or should I store it in a local state and update Redux store at once?
Will there be a performance issue if I dispatch action to Redux store on every keypress since it is not an asynchronous call.
Well, the answer is: it depends.
Some argue that we loose some of the advantages of using a central store (like Redux) if you also have an internal state in the components. Like, if all your application state is just the redux store, storing the store, or the sequence of actions that lead to that store, will give you a complete picture of what was happening before maybe an error occurs.
I believe that is excessive. It is completely fine to store little stuff in your component's internal state, but there should be a well defined line.
In case of a form, you'd have controlled input elements, and you'll want a mechanism to submit the form with an action. It'd be necessary to have the contents of the form in the redux store.
One way would be to have the contents in an internal state, and only put them into redux form after a little debounce. But that has some edge cases. What if the user submits the form in the little debounce time? The form in the store is incomplete. Is thinking about all the edge cases worth it?
I believe just having the form elements controlled from the redux form is the simplest solution. The performance issue one would imagine is not really an issue. This is also what redux-form does (you can look at how that is implemented for inspiration).

Managing field values with redux-form

Typically, when I've created a form in react/redux myself, I have managed the inputs as 'controlled components', meaning when an input box changes, it calls a function that updates a variable that is fed back into the input. Of course, for me, this is the crux of redux, it's the flow.
However with redux-form, it seems I have no ability to do this on each of the fields. Almost as if, the fields are controlled, but within redux-form's own world, as far as I'm concerned they're not controlled as I'm not passing a value and re-acting to a change with a callback.
This is causing me a problem, as I may have something else that updates those input fields. For example a postcode lookup might update an address's fields. Before I transitioned to redux-form, the 'flow binding' meant I could update those fields from a different reducer as they essentially just represented a live slice of the redux store.
How do I get around this?
Edit: I think the best approach might be to use this https://redux-form.com/7.0.3/examples/selectingFormValues/, but I'm not sure
Field values of redux forms can be modified using the reducer plugin. Basically you can add your own reducer to the one of redux form anf modify forms state like values, touched etc. Check it out here:
http://redux-form.com/7.0.3/docs/api/ReducerPlugin.md/
Be aware is an advanced usage of redux and redux forms.

Best approach to use nested reducer in React-Redux If same store value are used on same page

I am using same filter two time same screen for different purpose. Now updating at one place automatically updates the dependent values on second filter as well.
You are going to need two states in your Redux store - one for each filter. Then you need to connect one state to one filter, and the other state to the other filter.
You don't need to duplicate your reducers and actions though. Your action could take an filterId as input, and then pass this down to the reducer. The reducer updates different states based on which filterId is passed in from the action.
Hope that makes sense! Feel free to add follow up questions or additional information about your problem to get a more detailed explanation!

Resources