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

背景

在参与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} />
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值