useMemo
把“创建”函数和依赖项数组作为参数传入 useMemo,它仅会在某个依赖项改变时才重新计算 memoized 值。这种优化有助于避免在每次渲染时都进行高开销的计算。
官网是这么描述的,个人感觉跟vue的computed(计算属性)挺相似的。看下面一个案例
import { Button } from 'antd'; import React, { useEffect, useMemo, useState } from 'react' export default function Home() { const [num, setNum] = useState(0); const computedNum = useMemo(() => { return num * 10 }, [num]); const onClick = () => { setNum(num + 1) } useEffect(() => { }, []); return ( <div> {num} <Button onClick={onClick}>添加</Button> <div>计算后的值{computedNum}</div> </div> ) }
当num发声了变化的时候,那么就会重新计算,然后返回一个 memoized 值
Memoization是JavaScript中的一种技术,通过缓存结果并在下一个操作中重新使用缓存来加速查找费时的操作
useCallback+Memo解决重复渲染
首先假设一个这样的场景,子组件需要改变父组件的state,但是每次父组件发现值发生了变化,就会重新渲染,那么子组件发现了每次传来的props都改变了,然后子组件跟着重新渲染了,这样比较浪费性能,小的组件看不出来什么,但是如果子组件是一个非常庞大的组件,里面各种异步,那么问题就很明显了。
useCallback会将我们传递给它的函数fnB返回,并且将这个结果缓存;当依赖a变更时,会返回新的函数。
import { Button } from 'antd'; import React, { memo, useCallback, useEffect, useMemo, useState } from 'react' const Child = (props: any) => { console.log(props, '重新渲染'); return <Button onClick={props.handleSubmit}> 子组件改变父组件值</Button> } export default function Home() { const [num, setNum] = useState(0); const [random, setRandom] = useState(0); const computedNum = useMemo(() => { return num * 10 }, [num]); const onClick = () => { setNum(num + 1) } const handleSubmit = () => { setRandom(Math.random()) } return ( <div> {num} <Button onClick={onClick}>添加</Button> <div>随机数{random}</div> <div>计算后的值{computedNum}</div> <Child handleSubmit={handleSubmit} /> </div> ) }
首先有两个state,一个自增,一个随机数,然后通过子组件去改变随机数。也就是说当我们父组件num自增的时候,并不希望子组件重新渲染,因为子组件完全没有依赖num自增这个状态值,但事实是每次改变num的值,组件也会render。
可以使用useCallback+memo解决这种问题,每次子组件渲染是因为,父组件的num发声了变化后,重新渲染了,导致子组件的props也发声了变化,可以使用useCallback缓存的机制解决。
import { Button } from 'antd'; import React, { memo, useCallback, useEffect, useMemo, useState } from 'react' const Child = memo((props: any) => { console.log(props, '重新渲染'); return <Button onClick={props.handleSubmit}> 子组件改变父组件值</Button> }) export default function Home() { const [num, setNum] = useState(0); const [random, setRandom] = useState(0); const computedNum = useMemo(() => { return num * 10 }, [num]); const onClick = () => { setNum(num + 1) } //每次random状态发生变化,重新生成一个函数。 const handleSubmit = useCallback(() => { setRandom(Math.random()) }, [random]); return ( <div> {num} <Button onClick={onClick}>添加</Button> <div>随机数{random}</div> <div>计算后的值{computedNum}</div> <Child handleSubmit={handleSubmit} /> </div> ) }
这样每次父组件的num发生改变,但是子组件并没有重新渲染
https://www.cnblogs.com/sk-3/p/13808854.html
发表评论
侧栏公告
寄语
譬如朝露博客是一个分享前端知识的网站,联系方式11523518。
热评文章
标签列表
热门文章
友情链接