- 如果你希望你的组件props没变化的时候就不重新渲染,就可以用
React.memo
:点击button1,child不会刷新,点击button2,child才会刷新
const App = () => {
const [n, setN] = useState(0)
const [m, setM] = useState(0)
const onClick = () => {
setN(i => i + 1)
}
const onClick2 = () => {
setM(i => i + 1)
}
return (
<div>
<div>
<button onClick={onClick}>button1: update n {n}</button>
<button onClick={onClick2}>button2: update m {m}</button>
</div>
<Child2 data={m}/>
</div>
)
}
const Child = (props) => {
console.log('child执行了');
return (
<div>child:{props.data}</div>
)
}
const Child2 = React.memo(Child)
- 但是这种方式,只要加了监听事件,就立马破功:
点击button1,Child2组件会重新渲染
,原因是:点击之后,App会重新执行,onClickChild会成为一个新的函数,就意味着传给Child2的函数地址变化了,相当于props变了,就会重新刷新了;而m是值,是同一个值,意味着不变
,这时,我们可以用useMemo
const App = () => {
const [n, setN] = useState(0)
const [m, setM] = useState(0)
const onClick = () => {
setN(i => i + 1)
}
const onClick2 = () => {
setM(i => i + 1)
}
const onClickChild = () => {
}
return (
<div>
<div>
<button onClick={onClick}>button1:update n {n}</button>
<button onClick={onClick2}>button2:update m {m}</button>
</div>
<Child2 onClick={onClickChild} data={m}/>
</div>
)
}
const Child = (props) => {
console.log('child执行了');
return (
<div onClick={props.onClick}>child:{props.data}</div>
)
}
const Child2 = React.memo(Child)
- useMemo:
useMemo(()=>value,[deps])
,这里value可以是函数,对象等,useMemo类似vue的计算属性
,依赖缓存
。由于这是一个返回函数的函数,所以很奇怪,于是有了后面的useCallback
,useCallback就是useMemo的语法糖
,功能完全一样
const App = () => {
const [n, setN] = useState(0)
const [m, setM] = useState(0)
const onClick = () => {
setN(i => i + 1)
}
const onClick2 = () => {
setM(i => i + 1)
}
const onClickChild = useMemo(()=>{
return ()=>{}
},[m])
// 这里加m这个依赖的原因是,这个函数可能用到了m,意思是只有m变化了,才重新生成一个新的函数
return (
<div>
<div>
<button onClick={onClick}>update n {n}</button>
</div>
<Child2 onClick={onClickChild} data={m}/>
</div>
)
}
const Child = (props) => {
console.log('child执行了');
return (
<div onClick={props.onClick}>child:{props.data}</div>
)
}
const Child2 = React.memo(Child)
const App = () => {
const [n, setN] = useState(0)
const [m, setM] = useState(0)
const onClick = () => {
setN(i => i + 1)
}
const onClick2 = () => {
setM(i => i + 1)
}
const onClickChild = useCallback(
() => {
}, [m]
)
return (
<div>
<div>
<button onClick={onClick}>update n {n}</button>
<button onClick={onClick2}>update m {m}</button>
</div>
<Child2 onClick={onClickChild} data={m}/>
</div>
)
}
const Child = (props) => {
console.log('child执行了');
return (
<div onClick={props.onClick}>child:{props.data}</div>
)
}
const Child2 = React.memo(Child)