How to remove persisting states in modal component?
If you don't understand what I mean by persisting states in modal components, then once quickly have to look at the sandbox below:
The code used is pretty simple:
import * as React from "react";
import FormModal from "./FormModal";
function App() {
const [open, setOpen] = React.useState(false);
return (
<div>
<button onClick={() => setOpen(true)}>Open modal</button>
<FormModal open={open} onClose={() => setOpen(false)} />
</div>
);
}
export default App;
The formModal is just a modal component with an input element.
Steps:
- Click on Open Modal to open the modal
- Enter anything in the input
- Close the modal by clicking away from the modal
- Open the modal again
If you follow the steps above you should see the data that you entered in the modal remained unchanged (persisted) when you opened the modal next time. That's because even if the prop open has changed the component is still mounted and when rendered on the next time the previously mounted element is returned. Since the component instance hasn't been unmounted its states are preserved.
But what if you want a fresh modal each time the modal is opened? What if you don't want those lingering states?
You could simply mount and unmount the modal conditionally.
function App() {
const [open, setOpen] = React.useState(false);
return (
<div>
<button onClick={() => setOpen(true)}>Open modal</button>
{open && <FormModal open={open} onClose={() => setOpen(false)} />}
</div>
);
}
In the code above, since we've conditionally rendered FormModal component based on the boolean value open, each time when the value of open is falsy the FormModal component is unmounted while on true value the component gets re-mounted. This removes the preserving states of the modal component.
Also, if you've understood the importance and the use of the key prop, you could simply use it as well.
Kent C. Dodds has explained it well in his blog.
Whenever the key prop on any component changes, the components get re-mounted and thus loses their previous states. And yes you can use the key prop on any components not only to remove the warning of react while rendering the list.
So, the above code can also be modified as below with key to achieve the avoid the persistence of state.
function App() {
const [open, setOpen] = React.useState(false);
return (
<div>
<button onClick={() => setOpen(true)}>Open modal</button>
<FormModal open={open} onClose={() => setOpen(false)} key={open}/>
</div>
);
}