React 有一个特点,那就是当父组件重新 render 的时候,无论传入子组件的 props 有没有变化,子组件都会重新渲染。
搞懂 useMemo 之前,先弄懂 React.memo
React.memo
function App() {
const [n, setN] = useState(0)
const [m, setM] = useState(0)
const onClick1 = () => {
setN(i => i + 1)
}
const onClick2 = () => {
setM(i => i + 1)
}
return (
<div className="App">
<div>
<button onClick={onClick1}>update n {n}</button>
<button onClick={onClick2}>update m {m}</button>
</div>
<Child data={m}/>
{/*<Child1 data={m}/>*/}
</div>
)
;
}
const Child = React.memo((props) => {
console.log("Child执行了")
console.log("这里有大量的代码")
return (
<div>child: {props.data}</div>
)
})
React默认有多余的render,React.memo使得一个组件只有props变化的时候才更新
props不变,没有必要再执行一次函数组件
import React, {useState} from 'react';
function App() {
const [n, setN] = useState(0)
const [m, setM] = useState(0)
const onClick1 = () => {
setN(i => i + 1)
}
const onClick2 = () => {
setM(i => i + 1)
}
const onClickChild = () => {//这个函数跟着App一起重新执行,对象重新执行得到新的地址
}
return (
<div className="App">
<div>
<button onClick={onClick1}>update n {n}</button>
<button onClick={onClick2}>update m {m}</button>
</div>
<Child data={m} onClick={onClickChild}/>
{/*<Child1 data={m}/>*/}
</div>
)
;
}
const Child = React.memo((props) => {
console.log("Child执行了")
console.log("这里有大量的代码")
return (
<div onClick={props.onClick}>child: {props.data}</div>
)
})
export default App;
props上绑定事件,每次事件函数随App一起重新执行,生成新的函数,新旧函数地址不一样,props继而发生变化,memo监听到props变化,组件一起更新
useMemo
特点
- 第一个参数是无参函数
()=>{return value}
- value的类型是对象,比如函数,对象
- 第二个参数是依赖
[]
- 只有当依赖发生变化时,才会计算新的value
- 如果依赖不变,用之前的value
- 很像Vue2的computed,value是计算出来的,会缓存使用之前的值
注意
- 使用useMemo函数重用的方法:value是函数
const onClickChild = useMemo(() => () => {},[m])
这是一个返回函数的函数
是不是特别难用?于是就有了useCallback
useCallBack
useCallBack是useMemo的语法糖,直接写函数即可,不用函数返回函数
const onClickChild = useCallback(() => {},[m])
总结
一般先用memo,如果不行,再useMemo,如果觉得useMemo不好用,使用useCallBack
网友评论