I'm making a form component with React, and want to store the form(s) and field(s) state with Redux.
So I have a form reducer and a formField reducer.
I first followed my gut feeling and tried nesting the formField reducer in the form reducer. This basically meant having the formField-related switch cases in both the form reducer and the formField reducer.
This felt a bit messy (repeating code), so I read more in the documentation, and found out it is recommended to normalize the state. So I took away the nested formFields and put them at the same level as forms.
This made the reducer nice and clean, but now retrieving the formFields for a specific form feels horrible. I'm basically looping through all the formFields every time and only returning those with the correct "formId" parameter.
The Redux documentation states you should treat the state as a normalized database, but didn't he forget that you don't have the luxury of being able to query for results?
Did I miss anything here? What is the recommended way to solve this?
A normalized state is a way to store (organize) data. With this way each entity type will have its own place in the store, so that there is only a single point of truth. This practice is the recommended way to organize data in a Redux application as you can read in the Redux recipes.
If the new state is different, the reducer must create new object, and making a copy is a way to describe the unchanged part.
Redux and Normalization Normalization is the concept of flattening data and this comes with great performance increases because data is referenced directly and instantly rather than looped over. This is because normalized nested data is represented by ids which are later used to reference that data.
With the Redux Persist library, developers can save the Redux store in persistent storage, for example, the local storage. Therefore, even after refreshing the browser, the site state will still be preserved.
It sounds like you keep formFields
state as an array but want to query it as an object with formId
being the key:
This made the reducer nice and clean, but now retrieving the formFields for a specific form feels horrible. I'm basically looping through all the formFields every time and only returning those with the correct "formId" parameter.
If you change formFields
state to be an object, it will be much easier to query: formFields[fieldId]
.
As noted in the other answer, you can use to write composable “selectors” that define how to compute derived state. Then your components’ code will be simple because all heavy lifting of preparing the data handles in small and composable selectors.
You can check out reducers and selectors in the shopping-cart example to get a better idea of how the state is structured in idiomatic Redux apps. Note that this example uses vanilla functions for selectors but we recommend using Reselect for better performance.
From what I understand your issue is about querying derived data. (i.e. fields that belong to form X).
There is also a utility tool called reselect, your use-case seems to fit with what it solves.
You would just need to write a selector that expects a formId and it would return an array of form fields.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With