在没风的地方找太阳  在你冷的地方做暖阳 人事纷纷  你总太天真  往后的余生  我只要你 往后余生  风雪是你  平淡是你  清贫也是你 荣华是你  心底温柔是你  目光所致  也是你 想带你去看晴空万里  想大声告诉你我为你着迷 往事匆匆  你总会被感动  往后的余生  我只要你 往后余生  冬雪是你  春花是你  夏雨也是你 秋黄是你  四季冷暖是你  目光所致  也是你 往后余生  风雪是你  平淡是你  清贫也是你 荣华是你  心底温柔是你  目光所致  也是你
jQuery火箭图标返回顶部代码 - 站长素材

useCallback 和 useMeme 具体使用场景介绍

一、先说一下react

react是基于数据是不可变的(每次setState都会返回一个新数据),这也是为什么需要setState()来更新数据而不能使用像vue的this.state = newState的形式更新数据的原因,其实你用this.state=newState确实可以改数据,但是react不知道数据变了。

 

二、useMemo、useEffect的执行时机对比

useMemo和useCallback都会在组件第一次渲染的时候执行,之后会在其依赖的变量发生改变时再次执行;并且这两个hooks都返回缓存的值,useMemo返回缓存的变量,useCallback返回缓存的函数。

 

三、useMemo的使用场景

使用过vue的话,你可以把它理解成vue里面的computed,是一种数据的缓存,而这个缓存依赖后面的第二个参数数组,如果这个数组里面传入的数据不变,那么这个useMemo返回的数据是之前里面return的数据。

在具体项目中,如果你的页面上展示的数据是通过某个(某些)state计算得来的一个数据,那么你每次这个组件里面无关的state变化引起的重新渲染,都会去计算一下这个数据,这时候就需要用useMemo(()=>{}, [])去包裹你的计算的方法体,这样那些无关的state改变引起的渲染不会重新计算这个方法体,而是返回之前计算的结果,达到一种缓存的效果。

export default function WithMemo() {
    const [count, setCount] = useState(1);
    const [val, setValue] = useState('');
    const expensive = useMemo(() => {
        console.log('compute');
        let sum = 0;
        for (let i = 0; i < count * 100; i++) {
            sum += i;
        }
        return sum;
    }, [count]);
 
    return <div>
        <h4>{count}-{expensive}</h4>
        {val}
        <div>
            <button onClick={() => setCount(count + 1)}>+c1</button>
            <input value={val} onChange={event => setValue(event.target.value)}/>
        </div>
    </div>;
}

 

四、useCallback使用场景

useCallback跟useMemo比较类似,但它返回的是缓存的函数。

hooks组件state改变后会引起父组件的重新渲染,而每次重新渲染都会生成一个新函数,所以react子组件props在浅比较的时候就会认为props改变了,引起子组件不必要的渲染。

使用场景是:有一个父组件,其中包含子组件,子组件接收一个函数作为props;通常而言,如果父组件更新了,子组件也会执行更新;但是大多数场景下,更新是没有必要的,我们可以借助useCallback来返回函数,然后把这个函数作为props传递给子组件;这样,子组件就能避免不必要的更新。

为什么useCallback需要配合React.memo来使用?

react的Hooks组件对props的浅比较是在memo里面比较的(类组件是在shouldComponentUpdate里面),如果没有memo,那么你使用useCallback就没啥意义,反而浪费性能(因为useCallback来包裹函数也是需要开销的)。因为子组件还是会重新渲染。

function APP() {

    const [value, setValue] = useState(123)
    const [otherValue, setOtherValue] = useState(999)

    const changeValue = useCallback(() => {
        setValue(value => value+1)
    }, [])
    
    console.log('APP');

    return (
        <div>
            <div>与Message渲染无关的数据==={otherValue}</div>
            <br />
            <button onClick={() => setOtherValue(value => value-=5)}>改变无关的数据</button>
            <br />
            <br />
            <Message value={value} changeValue={changeValue} />
        </div>
    )
}

const Message = memo(
    function Message({value, changeValue}) {
    
        console.log('Message');
    
        return (
            <div>
                <button onClick={changeValue}>改变有关数据</button>
                <p>与Message渲染有关的数据{value}</p>
            </div>
        )
    }
)

 

posted @ 2021-05-18 17:00  艺术诗人  阅读(6746)  评论(0编辑  收藏  举报