网上的教程看得挺乱的, 还是心愿大家手动打代码, 去体验下, 印象更好
React.memo 和 useMemo 都是缩小组件中不必要的开销, 晋升性能
其中, memo是子组件自身是否渲染, useMemo则是子组件prop监听函数
memo
memo 很像shouldComponentUpdate生命周期还判断组件是否渲染
不应用memo
const Child = ({ name, children }: any) => { function changeName(name: string) { console.log("changeName"); return name + "扭转name的办法"; } console.log("Child组件更新"); const otherName = changeName(name); return ( <> <div>{otherName}</div> <div>{children}</div> </> );};function Parent() { const [count, setCount] = useState(0); const [name, setName] = useState("名称"); return ( <> <div>{count}</div> <button id="btn1" onClick={() => setCount(count + 1)}>count</button> <button id="btn2" onClick={() => setName(new Date().getTime() + "")}>name</button> <Child name={name}></Child> </> );}export default Parent;
点击btn1, btn2按钮二者都会触发Child了, 都会打印
Child组件更新changeName
点击btn1, Child没用count属性却还是渲染了, 所以就有了memo
批改Child.tsx
const Child = React.memo(({ name, children }: any) => { function changeName(name: string) { return name + "扭转name的办法"; } console.log("Child组件更新"); const otherName = changeName(name); return ( <> <div>{otherName}</div> <div>{children}</div> </> );});
点击btn1, 就不会在触发Child了
useMemo
useMemo 更加具体到组件外部的调用办法
const Child = ({ name, children }: any) => { function changeName(name: string) { console.log("changeName"); return name + "扭转name的办法"; } console.log("Child组件更新"); const otherName = changeName(name); return ( <> <div>{otherName}</div> <div>{children}</div> </> );};function Parent() { const [name, setName] = useState("名称"); const [content, setContent] = useState("内容"); return ( <> <button id="btn1" onClick={() => setName(new Date().getTime() + "")}>name</button> <button id="btn2" onClick={() => setContent(new Date().getTime() + "")}>content</button> <Child name={name}>{content}</Child> </> );}
点击btn1, btn2按钮二者都会触发Child了, 都会打印
Child组件更新changeName
点击btn2的时候, 因为Child从新渲染, 所以导致changeName也跟着打印了
然而btn2只扭转content, 没扭转Child中changeName须要的属性name,
对此, 咱们心愿扭转content的时候, 不触发组件中changeName函数, 因为changeName只应用到name属性, 因而咱们应该应用useMemo
const Child = ({ name, children }: any) => { function changeName(name: string) { console.log("changeName"); return name + "扭转name的办法"; } console.log("Child组件更新"); const otherName = useMemo(() => changeName(name), [name]); return ( <> <div>{otherName}</div> <div>{children}</div> </> );};
但咱们点击btn2的时候, 只触发了
Child组件更新