目录概念useMemo栗子筛选偶数每秒获取时间刷新页面如何优化useCallback、React.memo总结概念 react 中是通过一次次的 re-render (重新渲染)保持
react
中是通过一次次的 re-render
(重新渲染)保持我们的值及时的更新到页面上的,每次重新渲染都是一次快照,可以把它想象成一张张的照片,在某个时刻它应该是什么样子的
useMemo
,它仅仅会在数组依赖项中的值改变时才会重新计算值以下代码实现功能:找出 0
到 count
之间所有的偶数,count
可以动态改变,实时渲染在页面上,count
改变则会引起 re-render
import React, { useState } from 'react';
export default () => {
const [count, setCount] = useState(100);
const arr = [];
for (let i = 0; i < count; i++) {
if (i % 2 === 0) {
arr.push(i);
}
}
return (
<>
<fORM>
<label htmlFor="num">Your number:</label>
<input
type="number"
value={count}
onChange={(event) => {
// 设置最大值为 100000
let num = Math.min(100_000, Number(event.target.value));
setCount(num);
}}
/>
</form>
<p>
有{arr.length}偶数在 0 到 {count} 之间:<span>{arr.join(', ')}</span>
</p>
</>
);
};
下面代码增加了计时器,在页面显示实时的时间,这样页面每秒钟都会 re-render
,也会每秒钟重新筛选一次偶数(尽管 count
并没有变化)
import React, { useState, useEffect } from 'react';
export default () => {
const [count, setCount] = useState(100);
const [curTime, setCurTime] = useState('');
const useTime = () => {
useEffect(() => {
const intervalId = window.setInterval(() => {
let time = new Date();
setCurTime(time.toLocaleString());
}, 1000);
return () => {
window.clearInterval(intervalId);
};
}, []);
return curTime;
};
const time = useTime();
const arr = [];
for (let i = 0; i < count; i++) {
if (i % 2 === 0) {
arr.push(i);
}
}
return (
<>
<form>
<div>{time}</div>
<label htmlFor="num">Your number:</label>
<input
type="number"
value={count}
onChange={(event) => {
// 设置最大值为 100000
let num = Math.min(100_000, Number(event.target.value));
setCount(num);
}}
/>
</form>
<p>
有{arr.length}偶数在 0 到 {count} 之间:<span>{arr.join(', ')}</span>
</p>
</>
);
};
那我们需要的是啥,虽然每秒钟都在重新获取时间,但是我们的 count
如果并没有变化的话,我们没必要去一直重新计算它的,特别如果 count
的值特别大的时候,特别如果在一些旧设备上看着就会显得卡顿,极其影响性能 有了 useMemo 就是 so easy 啊
我们来改造下计算偶数地方的代码:这样如果 count
不变的情况下,不会进行重复的计算,直接使用上次的值
const arr = useMemo(() => {
const temp = [];
for (let i = 0; i < count; i++) {
if (i % 2 === 0) {
temp.push(i);
}
}
return temp;
}, [count]);
既然讲到 useMemo 了,那么 useCallback、React.memo 也顺便说下吧,一个效果的东西,只不过将返回的值从对象变成了函数或者组件
下面看个小栗子:
// 父组件代码:一个计时器每秒更新时间,父组件每秒不停的 re-render,改变 count 值的 onCountChange 函数传入子组件
import React, { useState, useEffect, useCallback } from 'react';
import Child from './child';
export default () => {
const [count, setCount] = useState(100);
const [curTime, setCurTime] = useState('');
const useTime = () => {
useEffect(() => {
const intervalId = window.setInterval(() => {
let time = new Date();
setCurTime(time.toLocaleString());
}, 1000);
return () => {
window.clearInterval(intervalId);
};
}, []);
return curTime;
};
const time = useTime();
const onCountChange = () => {
setCount((count) => count + 100);
};
console.log('re-render-father');
return (
<>
<div>{time}</div>
<div>{count}</div>
<Child onCountChange={onCountChange} />
</>
);
};
// 子组件代码,接收 onCountChange 函数,并且用 React.memo 包裹函数
import React from 'react';
export default React.memo((props: any) => {
const { onCountChange } = props;
console.log('re-render-child');
return (
<>
<div
onClick={() => {
onCountChange();
}}
>
加100
</div>
</>
);
});
分析一下上面的栗子:
原因:父组件在不停的 re-render 每次都会重新创建函数,在 js 中虽然两个函数一模一样,但是不是一个引用的话就不相等,所以 React.memo 在进行浅比较的时候就认为 props 变化了,子组件也会 re-render,造成了无效优化
解决办法:既然知道了原因所在,那我们如何解决呢,那就让它是同一个函数不就好了,那就用到了 useCallback 进行优化
const onCountChange = useCallback(() => {
setCount((count) => count + 100);
}, []);
或者可以用 useMemo:返回变成函数即可
const onCountChange = useMemo(() => {
return () => {
setCount((count) => count + 100);
};
}, []);
由此可见 useCallback 为 useMemo 的语法糖而已
将函数用 useCallback 包裹一样就会使用缓存的值,不会重新创建函数,也就不会重复 re-render 组件了
到此这篇关于快速学会react中useMemo的文章就介绍到这了,更多相关react中的useMemo内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: 六分钟带你快速学会react中的useMemo
本文链接: https://www.lsjlt.com/news/175630.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0