《八》React.PureComponent & React.memo()

React.PureComponentReact.memo() 都是用来控制组件的重新渲染的,用于优化性能。

React.PureComponent 适用于类组件, React.memo() 适用于函数组件。

React.PureComponent

React.Component 有两个问题:

  1. 只要执行 setState(),即使不改变 state 状态数据,组件也会重新 render()
  2. 只要当前组件重新 render(),子组件就会自动重新 render() ,即使子组件中的 props 数据没有改变或者根本就没有用到父组件的任何数据。
class Parent extends React.Component {
  state = {
    message:'Hello,React'
  }

  handleClick = () => {
  	// 执行了 setState(),虽然 message 的值没有改变,但 Parent 组件也会重新 render();Child 子组件虽然没有用到 Parent 组件的任何数据,但 Child 子组件也会重新 render()
    this.setState({message: 'Hello,React'})
  }

  render() {
    console.log('Parent render')
    return (
     <>
       <h1 onClick={this.handleClick}>{this.state.message}</h1>
       <Child />
     </>
   )
 }
}

class Child extends React.Component {
  render() {
    console.log('Child render')
    return <h2>这是 Child 组件</h2>
  }
}

请添加图片描述

造成这种现象的原因是 React.Component 中的 shouldComponentUpdate() 总是返回 true。如果想要效率高,应该只有当组件的 state 或 props 数据发生变化时才重新 render()

React.PureComponent 重写了 shouldComponentUpdate() 方法,只有 state 或 props 数据有变化才返回 true,才会重新执行 render() 方法。

React.PureComponent 内部通过 shallowEqual() 方法对要更新的 state/props 和旧的 state/props 做了一层浅比较。对于其中的基本类型数据,只比较值;对于其中的引用类型数据,直接比较地址是否相同,不管里面内容变不变,只要地址一样,就认为没变。
请添加图片描述

class Parent extends React.PureComponent {
  state = {
    message:'Hello,React'
  }

  handleClick = () => {
  	// 虽然执行了 setState(),但是因为要更新的 state 中的 message 和旧的 state 中的 messafe 的值一样,所以 Parent 组件和 Child 子组件都不会重新 render()
    this.setState({message: 'Hello,React'})
  }

  render() {
    console.log('Parent render')
    return (
     <>
       <h1 onClick={this.handleClick}>{this.state.message}</h1>
       <Child />
     </>
   )
 }
}

class Child extends React.PureComponent {
  render() {
    console.log('Child render')
    return <h2>这是 Child 组件</h2>
  }
}

React.memo()

class Parent extends React.Component {
  state = {
    message:'Hello,React'
  }

  handleClick = () => {
  	// 即使传入 Child 子组件中的 message 没有任何变化,Child 子组件也会重新 render()
    this.setState({message: 'Hello,React'})
  }

  render() {
  	const {message} = this.state
    return (
     <>
       <h1 onClick={this.handleClick}>{message}</h1>
       <Child message={message} />
     </>
   )
 }
}

const Child = (props) => {
  console.log('Child render')
  return (
    <>
    	<h2>这是 Child 组件</h2>
        {props.message}
    </>
  ) 
}
export default Child

React.memo()是一个高阶函数,可以控制函数组件仅在它的 props 发生改变的时候进行重新渲染。有两个参数,第一个参数是一个纯函数的组件,第二个参数是一个函数,用于对比 props 控制是否刷新,与 shouldComponentUpdate() 功能类似。

class Parent extends React.Component {
  state = {
    message:'Hello,React'
  }

  handleClick = () => {
  	// 传入 Child 子组件中的 message 没有任何变化,Child 子组件不会重新 render()
    this.setState({message: 'Hello,React'})
  }

  render() {
  	const {message} = this.state
    return (
     <>
       <h1 onClick={this.handleClick}>{message}</h1>
       <Child message={message} />
     </>
   )
 }
}

const Child = (props) => {
  console.log('Child render')
  return (
    <>
    	<h2>这是 Child 组件</h2>
        {props.message}
    </>
  ) 
}
export default React.memo(Child)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`React.memo` 是 React 中的一个高阶组件,用于优化组件的性能。它与 `React.PureComponent` 类似,但适用于函数组件而不是类组件。 使用 `React.memo` 可以避免在某些情况下不必要的重渲染。当组件的 props 发生变化时,React 会重新渲染该组件。但如果 props 没有发生变化,就没有必要重新渲染组件。这时,`React.memo` 就可以发挥作用。 `React.memo` 的基本用法如下: ```jsx import React from 'react'; function MyComponent(props) { // 组件的渲染逻辑 } export default React.memo(MyComponent); ``` 在这个例子中,我们将 `MyComponent` 组件使用 `React.memo` 包裹起来,这样就可以实现组件的记忆功能。当 `MyComponent` 组件的 props 发生变化时,`React.memo` 会比较前后两个 props 是否相等,如果相等就不会重新渲染组件,否则就会重新渲染组件。 需要注意的是,`React.memo` 只会对 props 进行浅比较,因此如果 props 是一个对象或数组,而且它们的值发生了变化,但引用没有变化,`React.memo` 仍然会认为它们相等。在这种情况下,你需要手动处理 props 的深层次变化,或者使用其他的优化工具,例如 `useMemo`、`useCallback` 等等。 另外,需要注意的是,虽然 `React.memo` 可以帮助我们优化组件的性能,但也不应该滥用。在大多数情况下,React 自身已经能够很好地处理组件的渲染,并且重渲染通常也不会带来太大的性能问题。只有在某些情况下,例如组件渲染比较频繁,或者组件的渲染成本比较高时,才需要考虑使用 `React.memo` 进行优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值