Whats the difference between passing a ReactElement
as a property:
<RenderParam ReactElement={<Counter />} />
function RenderParam({ ReactElement }) {
return <div>{ReactElement}</div>;
}
and passing a function that returns a ReactElement
:
const instantiatedCounter = () => <Counter />;
<RenderParam ReactElement={instantiatedCounter} />
function RenderParam({ ReactElement }) {
return <div> <ReactElement /> </div>
}
I see there are differences in the lifecycle:
Counter
is executed for the second case:ReactElement changed (at RenderParam lifecycle)
component did mount (at Counter)
I dont see whats difference between them. Why first case its able to keep its state?
The first example passes a static JSX element <Counter />
as RenderParam
prop. The second example uses a function instantiatedCounter
, that allows to return a more dynamic JSX element, commonly referred to as Render props.
In the second case you lose state, because React treats the ReactElement
prop as a freshly defined component every time, unmounts the old one and mounts it again on every render cycle. What you want to do is call the ReactElement
prop to retrieve a JSX element as return value:
function RenderParam({ ReactElement }) {
return <div>{ReactElement()}</div>;
// not: return <div><ReactElement /></div>
}
You could as well define it with JSX syntax <div><ReactElement /></div>
. But then make sure, instantiatedCounter
is a static function and not re-created on every render, so the object reference stays same:
const instantiatedCounter = () => <Counter />;
// make it static in some way, so object reference doesn't change
export default function App() {
// .. and remove instantiatedCounter here
return <RenderParam ReactElement={instantiatedCounter} />
}