First you should know whats happening when using React and JSX
import React from 'react'
function SomeChildren() {
/* ... */
return null /* ... */
}
function LinkWrapper(props) {
/* ... */
return null /* ... */
}
function App() {
return (
<LinkWrapper uselink>
<SomeChildren />
</LinkWrapper >
)
}
When compiling JSX
, Function App
becomes
import React from 'react'
function App() {
return React.createElement(
LinkWrapper, // component
{ useLink: true }, // props
React.createElement(SomeChildren) // children
)
}
And at runtime when React calls your function, here is what your function will return
Replaced App
return with what kind of data React.createElement
is returning.
function App() {
return {
"$$typeof": Symbol(react.element),
"type": LinkWrapper,
"props": {
"useLink": true,
"children": {
"$$typeof": Symbol(react.element),
"type": SomeChildren,
"props": {}
}
}
}
}
So at every call, React will always get a new definition of your App
,
This will trigger to get the definition for all tree of components.
Note: This will not actually render to DOM anything. React just needs to know if anything changed.
Now for example you use React.memo
to memoize your LinkWrapper
const LinkWrapper = React.memo((props) => {
return null /* ... */
})
This will make React to receive previous LinkWrapper
return value if props were not changed.
Note: By default it will only shallowly compare complex objects in the props object.
Now let's come back at our App
function App() {
return (
<LinkWrapper uselink>
<SomeChildren />
</LinkWrapper >
)
}
As I explained above <SomeChildren />
always will return a new React definition.
This means that using React.memo
on LinkWrapper
will not have any effect.
Because children always will be a new definition.
If you want to also memoize children you will have to do it manually.
function App() {
const memoChildren = React.useMemo(() => <SomeChildren />, [])
return (
<LinkWrapper uselink>
{memoChildren}
</LinkWrapper >
)
}
This can also be wrote as
function App() {
const memoChildren = React.useMemo(() => <SomeChildren />, [])
return (
<LinkWrapper uselink children={memoChildren} />
)
}
Now memoChildren
will always have same value between re-renders
Now LinkWrapper
will also see that children did not change,
and will return last memoized value without calling the function again
Top comments (0)