React.memo的用法

本文深入探讨了React.memo的使用方法及其实现原理,通过对比PureComponent,解释了如何利用React.memo提升函数组件的性能,避免不必要的渲染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在线示例 https://codesandbox.io/s/myp00yr1xx?fontsize=14/react-memo
在使用function 作为statless组件的时候,我们通常是这样的:

const  Foo = (props) => {
  console.info(props.name);
  return <div>props.name={props.name}</div>
}
export default class Bar extends React.PureComponent {
   state={name: 'Foo'}
   render(){
   	return (
            <div>
               <input 
                type="text"
                value={this.state.name} 
                onChange={(e) => this.setState({name: e.target.value})} 
               />
   			   <Foo name='Foo' />
   		    </div>
       );
   }
}

执行这段代码后,输入框的值发生变化时,控制台一直有输出"Foo"。我们有时候会期望它与PureComponent一样,props内的属性没有发生变化时,组件不用重新渲染。这时候,React.memo(functionComponent, compareFunction)就可以派上用场了。与PureComponent相似,React.memo作用于function形式的组件,稍微修改下上面的代码。

const areEqual = (prevProps, nextProps) => {
	/** 与shouldComponentUpdate相似,但是这是用来判断prevProps和nextProps是否相等,相
	**  等返回true,组件不发生重新渲染;反之,组件重新渲染。主要用于性能优化,不要过于依
	**  赖,容易发生bug
	**/
	return prevProps.name === nextProps.name
}
const  Foo = React.memo((props) => {
   console.info(props.name);
   return <div>props.name={props.name}</div>
}, areEqual)
### React.memo 使用指南及示例 React.memoReact 提供的一个高阶组件,用于优化函数式组件的性能。它通过浅比较 props 来决定是否重新渲染组件,从而避免不必要的渲染[^1]。 #### 核心特性 - **默认行为**:React.memo 默认对所有 props 进行浅比较。 - **自定义比较逻辑**:可以通过传递第二个参数作为比较函数来自定义比较逻辑。 --- #### 示例 1:基本用法 以下是一个简单的例子,展示如何使用 `React.memo` 包裹组件以避免不必要的渲染。 ```jsx import React from 'react'; // 子组件:Child.jsx(未优化) function Child({ user }) { console.log("Child重新渲染"); return ( <div> 用户姓名:{user.name} </div> ); } // 使用 React.memo 包裹组件,启用浅比较 const MemoizedChild = React.memo(Child); export default function Parent() { const [count, setCount] = React.useState(0); const [user, setUser] = React.useState({ name: "张三" }); // 更新 count 不会触发 MemoizedChild 的重新渲染 return ( <div> <button onClick={() => setCount(count + 1)}>增加计数</button> <button onClick={() => setUser({ name: "李四" })}>更改用户</button> <div>当前计数:{count}</div> <MemoizedChild user={user} /> </div> ); } ``` 在上述代码中,点击“增加计数”按钮不会导致 `MemoizedChild` 重新渲染,因为它的 `user` prop 没有变化[^1]。 --- #### 示例 2:自定义比较逻辑 当需要更复杂的比较逻辑时,可以传递一个比较函数作为 `React.memo` 的第二个参数。 ```jsx import React from 'react'; function Counter({ count }) { console.log('Counter is rendering...'); return <div>{count}</div>; } // 自定义比较函数 const MemoizedCounter = React.memo(Counter, (prevProps, nextProps) => { // 如果 count 的值没有变化,则返回 true,表示不重新渲染 return prevProps.count === nextProps.count; }); function App() { const [count, setCount] = React.useState(0); const increment = () => setCount(count + 1); return ( <div> <MemoizedCounter count={count} /> <button onClick={increment}>Increment</button> </div> ); } export default App; ``` 在这个例子中,即使父组件重新渲染,`MemoizedCounter` 也会根据自定义比较函数决定是否重新渲染[^2]。 --- #### 注意事项 1. **浅比较限制**:React.memo 默认只进行浅比较,对于嵌套对象或数组可能无法正确识别变化。 2. **副作用处理**:如果组件内部存在副作用(如 API 调用),需要确保这些副作用不会因 memo 化而被忽略。 3. **性能权衡**:并非所有组件都需要使用 `React.memo`,过度使用可能导致额外的性能开销。 --- #### 与类组件的对比 在类组件中,类似的优化功能可以通过 `shouldComponentUpdate` 实现。然而,`React.memo` 是专门为函数式组件设计的工具。 ```jsx class OptimizedClassComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { return this.props.someProp !== nextProps.someProp; } render() { return <div>Class Component</div>; } } ``` 虽然类组件也可以实现类似的功能,但函数式组件结合 `React.memo` 更加简洁和现代化。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值