import React, {useState} from 'react';
import ReactDOM from 'react-dom';
function PageLayout({title, children}) {
return <div>
<h1>{title}</h1>
<input type="text"/>
{children}
</div>;
}
function Page2({setPage}) {
return <PageLayout title="Page2">
<button onClick={() => {setPage(() => Page1);}}>Test</button>
</PageLayout>
}
function Page1({setPage}) {
return <PageLayout title="Page1">
<button onClick={() => {setPage(() => Page2);}}>Test</button>
</PageLayout>
}
function App() {
let [Page, setPage] = useState(() => Page1);
return <Page setPage={setPage}/>;
}
ReactDOM.render(<App />, document.getElementById('app'));
https://codesandbox.io/embed/serene-browser-tehj4?fontsize=14
The above code is most intuitive pattern for build multiple page web app. -- Don't mind the setPage. Just focus Page component returns PageLayout instance.
But react's diff algorithm is not optimized for that pattern. If you click "Test" button. The text you inputed in input will lost.
So I proposal "Soft Component" concept. Two soft component will be treated as same component in diff algorithm. In the example, we change Page1 and Page2 to soft components. Thus solve the problem I shown above.
If the type of the component is changed, the diff algo will render the new component, ( if Page1 is rendered, on click react will unmout Page1 and render Page2 hence the PageLayout will also be unmounted ). I think it's just the way you render layout that should be changed.
Because React relies on heuristics, if the assumptions behind them are not met, performance will suffer.
The algorithm will not try to match subtrees of different component types. If you see yourself alternating between two component types with very similar output, you may want to make it the same type. In practice, we haven鈥檛 found this to be an issue.
Keys should be stable, predictable, and unique. Unstable keys (like those produced by Math.random()) will cause many component instances and DOM nodes to be unnecessarily recreated, which can cause performance degradation and lost state in child components.
https://reactjs.org/docs/reconciliation.html#tradeoffs
I think the Soft Component/Component is like macro/function of lisp. Both useful.
Without introduce Soft Component, we must write it as function call instead of component instance form.
The way you compose components is not quite a React-way. As @amazzalel-habib suggested, you might want to restructure components.
If you want to stick to your way (which I really not recommend to), your input state becomes a global state which should be managed accordingly.
The Page1's PageLayout and the Page2's PageLayout are two different components, toggling one to the other means it will complete the full process of life cycle including unMount. In my opinion, the behave is normal.
Most helpful comment
If the type of the component is changed, the diff algo will render the new component, ( if Page1 is rendered, on click react will unmout Page1 and render Page2 hence the PageLayout will also be unmounted ). I think it's just the way you render layout that should be changed.