Reputation: 3017
I was wondering if it's possible to conditionally wrap a React component without losing the state of the children.
In the sandbox, you can see when clicking the Increment button a few times, followed by the "Wrap children" or "Unwrap children" action, the counter is reset.
https://codesandbox.io/s/fervent-herschel-f62e2?file=/src/App.js
The relevant code can be seen here:
const ConditionalWrap = ({ condition, children }) => {
return (
<Fragment>
{condition ? (
<div>{children}</div>
) : (
children
)}
</Fragment>
);
};
Can anyone point me to a resource why this is happening? I guess the parent tree needs to stay the same, I'd just like to know why.
Is there some way to keep the state of all the children
when conditionally wrapping them in an element or context provider?
Upvotes: 7
Views: 3114
Reputation: 11037
There's explanations of the reconciliation in the react documentation.
React sees two elements of different types and so tears down the old and puts in a new.
There isn't a way to keep the state of all the children. It might be a good idea to either keep them wrapped in the same element. Or move the state into context, redux, or props that you pass down.
There is a library someone built for the purpose of reparenting: https://github.com/httptoolkit/react-reverse-portal
Upvotes: 3