- If the form state does not matter globally, it’s more than fine to keep it in the local state.
- A typical example would be entering your email into a login form, then clicking “Forgot password” and… seeing that other form have your email already!
- The form’s state is so complex, managing all of that with Redux would be even worse.
- Not every form affects the global state of your app, either.
- Because your form has to provide immediate feedback, because you need the UX to be top-notch.
You are using controlled input components to make your forms.
Because your form has to provide immediate feedback, because you need the UX to be top-notch.
You are using controlled input components to make your forms. Because your form has to provide immediate feedback, because you need the UX to be top-notch.
You are using Redux to manage your app’s state: things like current user and their data and so on.
At this point, you look at these two things and are kind of wondering:
Well, should you?
React state vs. Redux state
As Dam Abramov put it:
Use React for ephemeral state that doesn’t matter to the app globally and doesn’t mutate in complex ways. For example, a toggle in some UI element, a form input state. Use Redux for state that matters globally or is mutated in complex ways. For example, cached users, or a post draft.
The simplified version of the quote is: use React state for things that don’t matter globally, and use Redux for state that does matter.
He has a point. He did put form input state into the ephemeral category, but that’s not always the case, and I’ll show why.
That’s… good and all. What does it mean in practice, applied to forms?
Here are several reasons you might want to move that state into Redux:
That is, even after the form gets unmounted, you still want to access its state.
For example, if you enter your email into a login form, then close it, and then want to come back and see it. Another example would be saving a message draft when a user switches to another conversation.
You have to have several instances of the form, synced.
It’s not unheard of to have a login form in a modal, but also have some places in your app where the login form is embedded right there. Think a landing page.
Or, continuing the messaging example and drafts, you may have several ways to message. Facebook, for instance, has a messaging widget on every page, but it also has a separate messaging page. It currently does not save the drafts between these do, but it by all means could.
In those cases, you might want to sync their inputs with Redux, so that two forms at the same time can have them.
You want certain form state to have the impact on the rest of your app.
Like, show a spinner in the navigation bar while the form is being submitted.
Or make Clippy cover his eyes when a user enters their password.
(The depicted case doesn’t need Redux as the owl is part of the form. However, if your app has a persona that lives somewhere globally, like Clippy, this would apply.)
Your imagination is the limit here, really, but if anything in the form — some value, or whether some input is active, or such — is needed outside the form, Redux is where it’s at.
On another hand, here are the broad reasons to keep the state in a React container:
In short, if the form state does not matter globally, it’s more than fine to keep it in the local state.
Most of my forms start out with React state only. And it’s a great default, because nearly not every form needs to implement all those cases when Redux is needed.
However, when the UX person comes and asks for something you can’t have with React state alone, you have to be ready.
In general, structuring your React state and components according to the container/presentational component pattern would make such a React state → Redux transition very easy.
Even if you decide you do need to go down the Redux route, don’t trap yourself into thinking you now have to move every single bit of your container state into Redux.
In fact, this is rarely the case. Instead, identify the state that:
And once you have, make that into Redux state.
For example, if the goal is to persist the input values as in the login modal example, only login and password would go into the state. The piece of state that knows whether a certain input would still stay in the container component, because it’s not needed anywhere else.
Ultimately, there is no “right” or “wrong” answer in the abstract.
There may well be ways to make Clippy cover its eyes without Redux.
There may well be reasons to use Redux even for a one-off form. For example, if time-travel debugging is how you debug every single bug.
Every particular case is different and should be evaluated separately, taking into account:
And there’s no better person than you to make that call. You don’t need to be compatible with every Medium article out there. Different requirements = different solutions.