need some help ~
Child
const Child = ()=> <div>I'm Child</div
export default Child
Parent
const Parent = (props)=> <div>{props.children}</div>
export default React.memo(Parent)
const App = () => {
const [count, setCount] = useState(0)
return(
<div>
<button onClick={()=>setCount(count+1)}></button>
<Parent>
<Child></Child>
</Parent>
</div>
)
}
The Parent Component will rerender, so the memo not working because it's children is a function component
I know a way to solve by useMemo, but it's ugly and not friendly, do you have better ideas?
const App = () => {
const [count, setCount] = useState(0)
const children = useMemo(()=><Child></Child>,[])
return(
<div>
<button onClick={()=>setCount(count+1)}></button>
<Parent>
{children}
</Parent>
</div>
)
}
Wrap your <Child />
with React.memo
:
const Child = ()=> {
console.log('render') // fires only once - on initial render
return <div>I'm Child</div>
}
const MChild = React.memo(Child);
const Parent = (props)=> <div>{props.children}</div>
const MParent = React.memo(Parent)
const App = () => {
const [count, setCount] = useState(0);
return(
<div>
<button onClick={()=>setCount(count+1)}>increment {count}</button>
<MParent>
<MChild></MChild>
</MParent>
</div>
)
}
render(<App />, document.getElementById('root'));
const children = useMemo(()=><Child></Child>,[])
Is the easiest way to go. Using memo(Child)
wont work since jsx in fact returns a new object whenever you call <Child />
. React.memo
by default just use simple shallow comparison so there really is no other direct way to solve it. You can create your own function that would eventually support children and pass it to React.memo(MyComp, myChildrenAwareEqual)
.
Move <Parent><Child/></Parent>
into a separate component, and memoize that component instead:
const Family = memo(() => <Parent><Child/></Parent>);
const App = () => {
const [count, setCount] = useState(0);
return (
<>
<button onClick={() => setCount(count => count + 1)}>{count}</button>
<Family />
</>
)
}
const Memo = React.memo(({ children, value }) => {
return children
}, (prev, next) => prev.value === next.value)
And then to use it
function Title() {
const [count, setCount] = useState(0)
const onClick = () => {
setCount(c => c + 1)
}
const a = ''
return (
<>
<div onClick={onClick}>{count}</div>
<Memo value={a}>
<Child>
<Nothing2 a={a} />
</Child>
</Memo>
</>
)
}
When a
changes, Child renders, otherwise it bails out with previous render.
I outline the rational behind it in my blog, https://javascript.plainenglish.io/can-usememo-skip-a-child-render-94e61f5ad981
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.