马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
useMemo
useMemo 是 React 提供的一个性能优化 Hook。它的紧张功能是制止在每次渲染时实验复杂的盘算和对象重修。通过影象上一次的盘算效果,仅当依赖项变革时才会重新盘算,进步了性能,有点类似于Vue的computed。
React.memo
React.memo 是一个 React API,用于优化性能。它通过影象上一次的渲染效果,仅当 props 发生变革时才会重新渲染, 制止重新渲染。
用法
利用 React.memo 包裹组件[一样平常用于子组件],可以制止组件重新渲染。- import React, { memo } from 'react';
- const MyComponent = React.memo(({ prop1, prop2 }) => {
- // 组件逻辑
- });
- const App = () => {
- return <MyComponent prop1="value1" prop2="value2" />;
- };
复制代码 React.memo 案例
起首明白 React 组件的渲染条件:
- 组件的 props 发生变革
- 组件的 state 发生变革
- useContext 发生变革
我们来看下面这个例子,这个例子没有利用 memo 举行缓存,以是每次父组件的 state 发生变革,子组件都会重新渲染。
而我们的子组件只用到了 user 的信息,但是父组件每次 search 发生变革,子组件也会重新渲染, 如许就就造成了没须要的渲染以是我们利用 memo 缓存。- import React, { useMemo, useState } from 'react';
- interface User {
- name: string;
- age: number;
- email: string;
- }
- interface CardProps {
- user: User;
- }
- const Card = function ({ user }: CardProps) { // [!code --]
- const Card = React.memo(function ({ user }: CardProps) { // [!code ++]
- console.log('Card render'); // 每次父组件的 state 发生变化,子组件都会重新渲染
- const styles = {
- backgroundColor: 'lightblue',
- padding: '20px',
- borderRadius: '10px',
- margin: '10px'
- }
- return <div style={styles}>
- <h1>{user.name}</h1>
- <p>{user.age}</p>
- <p>{user.email}</p>
- </div>
- } // [!code --]
- }) // [!code ++]
- function App() {
- const [users, setUsers] = useState<User>({
- name: '张三',
- age: 18,
- email: 'zhangsan@example.com'
- });
- const [search, setSearch] = useState('');
- return (
- <div>
- <h1>父组件</h1>
- <input value={search} onChange={(e) => setSearch(e.target.value)} />
- <Card user={users} />
- </div>
- );
- }
- export default App;
复制代码 当我们利用 memo 缓存后,只有 user 发生变革时,子组件才会重新渲染, 而 search 发生变革时,子组件不会重新渲染。- import React, { useMemo, useState } from 'react';
- interface User {
- name: string;
- age: number;
- email: string;
- }
- interface CardProps {
- user: User;
- }
- const Card = React.memo(function ({ user }: CardProps) {
- console.log('Card render');
- const styles = {
- backgroundColor: 'lightblue',
- padding: '20px',
- borderRadius: '10px',
- margin: '10px'
- }
- return <div style={styles}>
- <h1>{user.name}</h1>
- <p>{user.age}</p>
- <p>{user.email}</p>
- </div>
- })
- function App() {
- const [users, setUsers] = useState<User>({
- name: '张三',
- age: 18,
- email: 'zhangsan@example.com'
- });
- const [search, setSearch] = useState('');
- return (
- <div>
- <h1>父组件</h1>
- <input value={search} onChange={(e) => setSearch(e.target.value)} />
- <div>
- <button onClick={() => setUsers({
- name: '李四',
- age: Math.random() * 100,
- email: 'lisi@example.com'
- })}>更新user</button>
- </div>
- <Card user={users} />
- </div>
- );
- }
- export default App;
复制代码 React.memo 总结
- 利用场景:
- 当子组件吸取的 props 不常常变革时
- 当组件重新渲染的开销较大时
- 当须要制止不须要的渲染时
- 优点:
- 通过影象化制止不须要的重新渲染
- 进步应用性能
- 镌汰资源斲丧
- 注意事项:
- 不要过分利用,只在确实须要优化的组件上利用
- 对于简朴的组件,利用 memo 的开销大概比重新渲染还大
- 如果 props 常常变革, memo 的效果会大打扣头
useMemo 用法
- import React, { useMemo, useState } from 'react';
- const App = () => {
- const [count, setCount] = useState(0);
- const memoizedValue = useMemo(() => count, [count]);
- return <div>{memoizedValue}</div>;
- }
复制代码 参数
入参
- 回调函数:Function:返回须要缓存的值
- 依赖项:Array:依赖项发生变革时,回调函数会重新实验(实验时机跟useEffect类似)
返回值
useMemo 案例
我们来看下面这个例子,这个例子没有利用 useMemo 举行缓存,以是每次 search 发生变革, total 都会重新盘算,如许就造成了没须要的盘算以是我们可以利用 useMemo 缓存,由于我们的 total 跟 search 没有关系,那么如果盘算的逻辑比力复杂,就造成了性能题目。- import React, { useMemo, useState } from 'react';
- function App() {
- const [search, setSearch] = useState('');
- const [goods, setGoods] = useState([
- { id: 1, name: '苹果', price: 10, count: 1 },
- { id: 2, name: '香蕉', price: 20, count: 1 },
- { id: 3, name: '橘子', price: 30, count: 1 },
- ]);
- const handleAdd = (id: number) => {
- setGoods(goods.map(item => item.id === id ? { ...item, count: item.count + 1 } : item));
- }
- const handleSub = (id: number) => {
- setGoods(goods.map(item => item.id === id ? { ...item, count: item.count - 1 } : item));
- }
- const total = () => {
- console.log('total');
- //例如很复杂的计算逻辑
- return goods.reduce((total, item) => total + item.price * item.count, 0)
- }
- return (
- <div>
- <h1>父组件</h1>
- <input type="text" value={search} onChange={(e) => setSearch(e.target.value)} />
- <table border={1} cellPadding={5} cellSpacing={0}>
- <thead>
- <tr>
- <th>商品名称</th>
- <th>商品价格</th>
- <th>商品数量</th>
- </tr>
- </thead>
- <tbody>
- {goods.map(item => <tr key={item.id}>
- <td>{item.name}</td>
- <td>{item.price * item.count}</td>
- <td>
- <button onClick={() => handleAdd(item.id)}>+</button>
- <span>{item.count}</span>
- <button onClick={() => handleSub(item.id)}>-</button>
- </td>
- </tr>)}
- </tbody>
- </table>
- <h2>总价:{total()}</h2>
- </div>
- );
- }
- export default App;
复制代码 当我们利用 useMemo 缓存后,只有 goods 发生变革时, total 才会重新盘算, 而 search 发生变革时, total 不会重新盘算。- import React, { useMemo, useState } from 'react';
- function App() {
- const [search, setSearch] = useState('');
- const [goods, setGoods] = useState([
- { id: 1, name: '苹果', price: 10, count: 1 },
- { id: 2, name: '香蕉', price: 20, count: 1 },
- { id: 3, name: '橘子', price: 30, count: 1 },
- ]);
- const handleAdd = (id: number) => {
- setGoods(goods.map(item => item.id === id ? { ...item, count: item.count + 1 } : item));
- }
- const handleSub = (id: number) => {
- setGoods(goods.map(item => item.id === id ? { ...item, count: item.count - 1 } : item));
- }
- const total = useMemo(() => {
- console.log('total');
- return goods.reduce((total, item) => total + item.price * item.count, 0)
- }, [goods]);
- return (
- <div>
- <h1>父组件</h1>
- <input type="text" value={search} onChange={(e) => setSearch(e.target.value)} />
- <table border={1} cellPadding={5} cellSpacing={0}>
- <thead>
- <tr>
- <th>商品名称</th>
- <th>商品价格</th>
- <th>商品数量</th>
- </tr>
- </thead>
- <tbody>
- {goods.map(item => <tr key={item.id}>
- <td>{item.name}</td>
- <td>{item.price * item.count}</td>
- <td>
- <button onClick={() => handleAdd(item.id)}>+</button>
- <span>{item.count}</span>
- <button onClick={() => handleSub(item.id)}>-</button>
- </td>
- </tr>)}
- </tbody>
- </table>
- <h2>总价:{total}</h2>
- </div>
- );
- }
- export default App;
复制代码 useMemo 实验时机(依赖项)
- 如果依赖项是个空数组,那么 useMemo 的回调函数会实验一次
- 指定依赖项,当依赖项发生变革时, useMemo 的回调函数会实验
- 不指定依赖项,不保举这么用,由于每次渲染和更新都会实验
useMemo 总结
- 利用场景:
- 当须要缓存复杂盘算效果时
- 当须要制止不须要的重新盘算时
- 当盘算逻辑复杂且耗时时
- 优点:
- 通过影象化制止不须要的重新盘算
- 进步应用性能
- 镌汰资源斲丧
- 注意事项:
- 不要过分利用,只在确实须要优化的组件上利用
- 如果依赖项常常变革,useMemo 的效果会大打扣头
- 如果盘算逻辑简朴,利用 useMemo 的开销大概比重新盘算还大
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |