memo useMemo useCallback 对应的是组件、值、函数的缓存处理
- memo 用于缓存组件的渲染结果,只有组件的 props 发生改变时才会重新渲染,可以避免不必要的渲染,从而提高性能。(memo(组件))
- useMemo 用于缓存计算结果(值、对象。。。),只有依赖的值发生改变时才会重新计算,可以避免不必要的计算,从而提高性能。(useMemo(值))
- useCallback 用于缓存函数引用,可以避免在每次渲染时都创建一个新的函数,从而提高性能。useCallback((函数))
当数据重新赋值时,整个组件会刷新渲染,当数据功能复杂且多,且部分数据无需刷新时,会被强制刷新,造成性能浪费,也可能会产出bug。那么这时候就需要用上useCallback和useMemo来缓存不需要更新的数据,形成memoized值,也就是缓存的值。memo则是用于子组件不重新渲染
什么都没有使用的情况下 Button点击会触发Child渲染
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child />
</div>)
}
const Child =() => {
console.log('child load')
return (
<Button>child text</Button>
)
}
export default Parent
memo 点击Button Child不再重复渲染
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child />
</div>)
}
const Child = memo(() => {
console.log('child load')
return (
<Button>child text</Button>
)
})
memo失效 点击Button Child又重复渲染
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
const clickBtn1 = () => {
setNum1(num1+1)
}
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child call={clickBtn1} />
</div>)
}
const Child = memo((props: any) => {
console.log('child load')
return (
<Button onClick={props.call}>child text</Button>
)
})
memo与useCallback结合使用 Child不再重复渲染
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn1 = useCallback(() => {
setNum1(num1+1)
},[num1])
const clickBtn = useCallback(() => {
setNum(num+1)
},[num])
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child call={clickBtn1} />
</div>)
}
const Child = memo(({call}: any) => {
console.log('child load')
return (
<Button onClick={call}>child text</Button>
)
})
传参给子组件 Button点击 Child会跟着渲染
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
const clickBtn1 = () => {
setNum1(num1+1)
}
const mockData = () => ({
newNum: num1
})
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child num={mockData.newNum} />
</div>)
}
const Child = memo((num}:any) => {
console.log('child load')
return (
<Button onClick={() => {}}>child text--{num}</Button>
)
})
传参给子组件 Button点击 Child不会跟着渲染
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
const clickBtn1 = () => {
setNum1(num1+1)
}
const mockData = useMemo(() => ({
newNum: num1
}),[num1])
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child num={mockData.newNum} />
</div>)
}
const Child = memo((num}:any) => {
console.log('child load')
return (
<Button onClick={() => {}}>child text--{num}</Button>
)
})
更改一下 Button点击 Child会跟着渲染
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
const clickBtn1 = () => {
setNum1(num1+1)
}
const mockData = useMemo(() => ({
newNum: num1
}),[num1])
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child num={mockData.newNum} call={clickBtn1}/>
</div>)
}
const Child = memo((call,num}:any) => {
console.log('child load')
return (
<Button onClick={call}>child text--{num}</Button>
)
})
这时候函数也要更改啦
const Parent = ()=> {
const [num, setNum] = useState(0)
const [num1, setNum1] = useState(0)
const clickBtn = () => {
setNum(num+1)
}
const clickBtn1 = useCallback(() => {
setNum1(num1+1)
},[num1])
const mockData = useMemo(() => ({
newNum: num1
}),[num1])
return (
<div>
<div>{num}</div>
<Button onClick={clickBtn} >+1</Button>
<Child num={mockData.newNum} call={clickBtn1}/>
</div>)
}
const Child = memo((call,num}:any) => {
console.log('child load')
return (
<Button onClick={call}>child text--{num}</Button>
)
})
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)