React基础(SCU,公共逻辑抽离)—第二部分

SCU、PureComponent与memo

SCU:shouldComponentUpdate

  • React默认:父组件有更新,子组件无条件更新!!
  • 因此在不需要进行更新的子组件中,在SCU可对数据进行判断,对不需要进行更新的子组件返回false(改方法默认返回true);
  • 此方法仅作为性能优化的方式而存在,且应该考虑使用React内置的 PureComponent组件,可先不使用SCU,有性能问题再考虑;
  • 不建议在 shouldComponentUpdate() 中进行深层比较或使用 JSON.stringify()。这样非常影响效率,且会损害性能;
  • 在SCU中一定要配合不可变值进行使用,例如在组件中对某一数据进行更改时,使用了push方法,那么当前的改数组的值与next数组的值则是相同的,那么就会导致即使数据有更改,但是在SCU中却判断不出来,导致问题出现;
  • 用法如下:如果当前的props.text与nextProps.text不同的时候才会发生渲染;
  shouldComponentUpdate(nextProps, nextState){
    if (nextProps.text !== this.props.text){
      return true;
    }
    return false;
  }

PureComponent和memo

  • PureComponent会对 propsstate进行浅层比较,并减少了跳过必要更新的可能性
  • 如果是在函数组件中,则使用memo
  • 使用如下;
Class App extends React.PureCOmponent{}
  • React.memo为高阶组件。它与 React.PureComponent非常相似,但只适用于函数组件,而不适用 class 组件;
  • React.memo默认情况下只对对象进行浅层比较,如果想要控制对比过程,那么请将自定义的比较函数通过第二个参数传入来实现;
function MyComponent(props){
  // 使用props进行渲染
}
function areEqual(prevProps, nextProps){
  /*
    与 class 组件中 shouldComponentUpdate() 方法不同的是,
    如果 props 相等,areEqual 会返回 true;
    如果 props 不相等,则返回 false。
    这与 shouldComponentUpdate 方法的返回值相反。
   */
}

export default React.memo(MyComponent, areEqual);

关于组件公共逻辑的抽离

  • mixin,已被React弃用
  • HOC,高阶组件
  • Render Props

高阶组件

  • 高阶组件不是一种功能,而是一种模式
  • redux connect是高阶组件
const HOCFactory = (Component) => {
  class HOC extends React.Component{
    // 在此定义多个组件的公共逻辑
    render (){
      return (
        <Component {...this.props} />   // 返回拼装的结果
      )
    }
  }
  return HOC;
}

const EnHancedComponent1 = HOCFactory(WrappedComponent1);
const EnHancedComponent2 = HOCFactory(WrappedComponent1);
  • 如下实现一个高阶组件,将获取鼠标位置抽离成公共逻辑
import React from 'react';

const App = (props) => {
  const {x, y} = props.mouse;
    return (
      <div style={{height:'500px'}}>
        <h1>The mouse positon is ({x}, {y})</h1>
      </div>
    )
}

const withMouse = (Component) => {
  class WithMouseComponent extends React.Component{
    constructor(props){
      super(props);
      this.state = {
        x:0,
        y:0
      }
    }
    handleMouseEvent = (event) => {
      this.setState({
        x: event.clientX,
        y: event.clientY
      })
    } 
    componentDidMount(){
      
    }
    render (){
      return (
        <div style={{height:'500px'}} onMouseMove={this.handleMouseEvent}>
          {/* 1、透传所有的props; 2、增加mouse属性 */}
          <Component {...this.props}  mouse={this.state} />
        </div>
      )
    }
  }
  return WithMouseComponent
}

export default withMouse(App);

Render Props

  • 核心思想:通过一个函数将class组件的state作为props传递给纯函数组件
import React from 'react';
import propTypes from 'prop-types';

const App = (props) => {
  return (
    <div style={{height:'500px'}}>
      <Mouse render = { ({x, y}) => {
       return (
       <h1>The mouse positon is ({x}, {y})</h1>
       )
      }}></Mouse>
    </div>
  )
}

class Mouse extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      x:0,
      y:0
    }
  }
  handleMouseEvent = (event) => {
    this.setState({
      x: event.clientX,
      y: event.clientY
    })
  } 
  render (){
    return (
      <div style={{height:'500px'}} onMouseMove={this.handleMouseEvent}>
        {/* 将当前的state作为props,传递给render, render是一个函数组件 */}
        {this.props.render(this.state)}
      </div>
    )
  }
}

Mouse.propTypes = {
  render: propTypes.func.isRequired // 必须接受一个render属性,
}

export default App;

HOC vs Render Props

  • HOC:模式简单,但会增加组件层级
  • Render Props:代码简洁,学习成本高
  • 按需使用
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值