How do you store and propagate state to nested ReactJS components? - reactjs

The scenario is this:
I have a form with dynamic (meaning they are not present on the initial render of the form) field sets.
So the main form would have fields for first_name, last_name, phone, etc and it would also have the possibility to add "rooms with items" like for example a bedroom with 2 chairs and a table.
I would like to store (to localStorage) and restore the state of the entire form (including it's dynamic components) but I'm having a hard time figuring out a way to easily do that.
I've tried storing everything in the main form's state but that becomes a nightmare to manage.
Is there anything that React provides for that purpose? Something that would allow me to take a snapshot and restore it later?
Thank you

What do you use with React ? If you were using redux I would suggest using redux form http://erikras.github.io/redux-form/#/examples/dynamic?_k=5pwhl7 - you would be able to easily serialise/deserialise the form state to be persisted.

Related

Use cases for when not to use redux?

I was always wondering if I should use redux store all the time even when it's not really necessary.
For example:
I have form with select field that has some options I fetch from API. Let's imagine that form is for adding new car listing and select options are car models. Should I directly call API from component and display options or should I create store CarModels or something like that and store results from API there and then map those values to state in component?
I have "Favorites" feature, when you click heart next to some item (let's say a car), do I need to go through dispatching all events FAVORITE_CAR_REQUEST, FAVORITE_CAR_SUCCESS etc... or is it good enough to just call API directly from component (using some kind of api-service of course).
It's related to question above. If I have screen where I show favorites, I should then probably have store and connect everything with actual favorite action so I update the list. On new favorite, API will return favorited item, should I push that one in list of favorites already in store or should I just load again latest list when user opens up the favorites screen?
Thanks in advance.
I think this is a perfectly valid question. What I feel like you're trying to ask is if you could/should mix react state and the redux store. The answer is sure! Just think about where you need to use that part of state before deciding where to store it. If you need a part of the state in multiple components, it probably makes sense to use Redux. If you only need state locally, perhaps to set form validation errors, maybe use react's state management if you feel like it. React and redux are both meant to be flexible, so as long as you're consistent in when you use the redux store and react state you should be good.
I found this article that also explains this pretty well: https://blog.jakoblind.no/is-using-a-mix-of-redux-state-and-react-local-component-state-ok/
I tend to use redux when the state has to be accessed globally / complex logic that i want to be logged properly

I want to collect state data from multiple components every time the state changes in each component

So I am tasked to build an application where each component(5 components) has 1 editable table(components have no hierarchy). I am required to record the edits made in each component and make an AJAX call to a backend. The data that I send is going to be the edits from all the 5 components. What is the best way to approach a situation like this one? Thanks in advance.
I think that all comes down to where you put the sate, if you put on top of the hierarchy you will be able to spread to all children when the state changes
Alright what I did end up doing is to store things in localStorage and retrieve them when appropriate.

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.

React nested Component, arbitrary communication

There are many answers regarding react component communication, but seems none of them resolved my problem. Here is my problem's detail. Please help! Thanks in advance.
I'm building a flexible form. The UI is generated by nesting components.
The form data structure could also be nested json objects.
i.e form can have some inputs and sections, sections can have some inputs or sections, and go on.
sections is just UI layout components, doesn't care about data or state.
But input (could be text input, checkbox etc anything to capture data)
The problem I'm facing is any input's validation could depends on any other inputs' value.
i.e inputA has validation expression like formData.inputB >formData.inputA + formData.inputC
But they could also have no dependency at all if you don't give a validation expression.
If I pass the whole formData down the component tree, every time I type in one input, the whole form will rerender.
I have considered redux, but real not sure how redux can help such case. I'm still relative new to react and redux, so I could be wrong.
So what could be a viable solution?
Its a common issue when you're modularizing form elements. I have the same problem.
Redux is by far the most controlled solution. All of the components can listen and update the same object simultaneously. But you can also attach functions as props from the parent that you bind to the parent. The function would fetch the state of the parent and update the state like a makeshift store. If you're a good developer, this is possible but neither are simple to do. Good time to learn :)
There are various solutions to your problem, but in general it shouldn't even be a problem, because rendering (even of large forms) should be quite effective with React.
The core tool for adjusting performance in React is the shouldComponentUpdate method of your component classes. If you're smart about what you pass to the individual form fields and then implement shouldComponentUpdate properly on them, you should be able to update only when needed. In your particular example, you don't need to pass the full object everywhere.
You can just pass value, onChange and isInvalid to each field and calculate the validity at the root (where you have access to the full state). Then the shouldComponentUpdate of your fields can decide just based on those props. (Obviously this is a simplistic example, but as a principle it's sound.)
Sure, Redux is another possible solution. If you keep the state in Redux store and only connect each of your fields to the portion of the state it needs, you should be all set. It brings quite a change in architecture though, so you should choose Redux only if you really want it for your app as a whole.

How to filter redux store data on several places

If I have redux store with list of cars.
And I use that list to populate several components like dropdown and for example table (which can be filtered).
When I filter table, my dropdown will be filtered to,
beside it's on other page, they share same store.
And if I clone that part of data in store I would loose option to add/edit on all places.
What are best practices for this kind of cases? And examples maybe?
You should avoid editing the store data from inside the components.
When you filter your list in the component - create a new, cloned instance of the list - to be sure you don't change anything in the store.
When you want to change anything in the store - use actions.
You should keep the Store data as readonly in Components.
I found a good article on this topic https://hackernoon.com/redux-step-by-step-a-simple-and-robust-workflow-for-real-life-apps-1fdf7df46092
As I can see this article explains this question well, didn't see it earlier:
http://redux.js.org/docs/recipes/ComputingDerivedData.html
So this could be correct way to filter or do anything else without polluting the store data.

Resources