Do you want to request a feature or report a bug?
Seems to me to be a bug ( maybe not a bug)
What is the current behavior?
The WrapAndRenderChildren component is being unmounted and mounted, so does the From hence when changing the input value (which in turn sets the state) the input is rerendered and loses focus.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:
What is the expected behavior?
The WrapAndRenderChildren component should only be updated when I modify the state not unmounted.
As React unmounts a component only when the type of the component or its key has changed. in my exemple the type does not change, but when I define the WrapAndRenderChildren outside of the App component it's seems to work correctly.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16.8
With the code snippet you provided, anytime state updates in your App component, you will re-create the WrapAndRenderChildren component because you are defining it within the App component.
To avoid this, you can hoist WrapAndRenderChildren up to the module scope and define it outside of your App component:
const WrapAndRenderChildren = function({ children }) {
useEffect(() => {
console.log("WrapAndRenderChildren Mounted");
return () => console.log("WrapAndRenderChildren Un-Mounted");
}, []);
// In another component, I'll wrappe children in a DialogContent for a popup or somthing instead of div.
// the idea is to reuse FormPage
return <div>{children}</div>;
};
function App() {
const [state, setState] = React.useState("");
return (
<FormPage
state={state}
setState={setState}
Wrapper={WrapAndRenderChildren}
/>
);
}
@hamlim thanks for the reply.
Yes that's what I mentioned, but the question is why? As far as the diff algo only rerenders a tree when the root's type or key has changed. In my case the type does not change.the reference may have changed.
In my case the type does not change.the reference may have changed.
That is exactly the problem. How does react know whether the type is the same or not? It just compares components by reference.
@vkurchatkin yeah, but I think the fiber type contains the name of the component, I wonder if that what defines the type of the component, if so my example should actually work 馃
@amazzalel-habib this is how JS works. You can read about equality here.
@miraage I have no problem with JS, I just wonder how the type of this component :
const WrapAndRenderChildren = function({ children }) {
return <div>{children}</div>;
};
Is different in next call of:
const WrapAndRenderChildren = function({ children }) {
return <div>{children}</div>;
};
@amazzalel-habib https://reactjs.org/docs/reconciliation.html
You create WrapAndRenderChildren function each render of App component, so the equality check will fail. It tells react "hey, there is a new component".
@miraage so react takes in consideration the reference of components, I thought it takes only the name of component as type and compare the type instead.
Thanks,