React高阶组件在业务场景下的应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/neoveee/article/details/80639062

背景

在参与beisenCloud和pageBuilder的对接任务中,出现了这样一个问题:有两个组件同时关联了同一个属性组件,并且在constructorcomponentDidMount内等做了一些初始化操作,当在这两个组件之间切换的时候,由于属性组件已经被首次render了,所以只进行了diff算法,并没有重新生成一个新的组件实例,从而导致了属性组件没有同步更新

方案

当然,我们可以在属性组件内添加componentWillReceiveProps生命周期方法,通过nextProps上的参数,将constructor或者componentDidMount内的初始化配置逻辑重新走一遍

然而,这涉及到一个问题:如果我们开发的很多属性组件,都有这个问题,那我们不得不在每个组件内部都实现一遍这样的逻辑,开发和维护的成本是很高的

在使用componentWillReceiveProps的时候,遇到一个问题需要注意下:在该方法之内,render之前调用的所有同步操作,通过this.props访问到的props都是旧的数据

优化

既然这逻辑是需要在多处复用的,那我们就需要将这部分逻辑抽离出来,放在高阶组件内完成,在需要的地方,通过该高阶组件装饰一下即可

该高阶组件接收一个条件方法,在componentWillReceiveProps生命周期方法中,将nextPropsthis.props暴露给条件方法,通过返回值用来控制是否需要重新实例化Target

高阶组件内部代码实现如下

//高阶组件,解决属性组件不刷新的问题
import React, { Component } from 'react'

export default conditionalFun => Target => class Decorator extends Component{
  constructor(props){
    super(props)
    this.state = {
      'newInstance': false
    }
  }

  componentWillReceiveProps (nextProps) {
    let result = conditionalFun(nextProps, this.props)

    if (result) {
      this.setState({ 'newInstance': true })
    } else {
      this.setState({ 'newInstance': false })
    }
  }

  render () {
    let { newInstance } = this.state;
    if (newInstance) {
      return <Target key={Date.now()}  {...this.props}/>//添加key,绕过diff,重新生成新的实例
    }
    return <Target {...this.props} />
  }
}

猜你喜欢

转载自blog.csdn.net/neoveee/article/details/80639062
今日推荐