I have the following code. Based on selected option
Switcher
renders specific SwitcherForm
.
const Switcher = ({ switcherType }: ISwitcher) => {
switch (switcherType) {
case Switchers.Dvd:
return <SwitcherForm {...SwitchersText[Switchers.Dvd]} />
case Switchers.Book:
return <SwitcherForm {...SwitchersText[Switchers.Book]} />
case Switchers.Furniture:
return (
<div className="switcher">
{SwitchersFurniture.map((item) => (
<SwitcherForm key={item.name} {...item} />
))}
<p className="switcher__descr">Please, provide dimensions.</p>
</div>
)
default:
return <></>
}
}
I checked through console.log
in UseEffect of SwitcherForm
that when case
changes from Switchers.Dvd
to Switchers.Book
or vice versa, the components doesn't rerender and unmount, they even share the state. It doesn't apply to when case
is Switchers.Furniture
.
Only if I set different key
attributes to SwitcherForm
they start normaly rerender and unmount.
CodePudding user response:
The primary way that react figures out whether it should create a new instance of the component or reuse the old one is by comparing the type of component from one render to the next. So if on render #1 you return a <SwitcherForm>
and on render #2 you return a <div>
, it sees that the types are different, and so it unmounts one and mounts the other.
But if you return a <SwitcherForm>
both times, react sees that the component type is identical. Thus, react will keep the current one (including its internal state) and just changes its props. You may have created those on different lines of code, but react just sees what you returned, not that you did a switch statement, etc.
So for cases like this you can use keys, which are the secondary way that react figures out which element corresponds to which. If the key changes, then react knows it should treat them as different, even though the type is the same.
See this page in the documentation for a more thorough walkthrough: https://beta.reactjs.org/learn/preserving-and-resetting-state