学习React系列(九)——高阶函数

定义:高阶组件就是一个函数,且该函数接收一个组件作为参数,并返回一个新的组件。

(上一篇已经说过了高阶组件可以用来解决交叉问题)

 

一、不要改变原始组件,使用组合

class A extends React.PureComponent{
  constructor(props){
    super(props);
    this.state={
      content:"我是A"
    }
  }
  componentWillReceiveProps(nextProps){
    this.setState({
      content:nextProps.content
    })
  }
  componentDidMount(){
    console.log("a挂载完毕")
  }
  render(){
    return(
      <p>{this.state.content}</p>
    )
  }
}

class B extends React.PureComponent{
  constructor(props){
    super(props)
    this.state={
      content:'我是B'
    }
  }
  componentDidMount(){
    console.log("b挂载完毕")
  }
  render(){
    return(
      <button style={{color:'red'}}>{this.state.content}</button>
    )
  }
}

function initContent(Aa){
  //  Aa.prototype.componentDidMount=function(){
  //    console.log("我先挂载好的")
  //  }
  return class K extends React.Component{
    constructor(props){
      super(props);
      this.state={
        content:"我是高阶组件生成的"
      }
    }
    componentDidMount(){
      this.setState({
        content:"我现在为C"
      })
      console.log("c挂载完毕")
    }
    render(){
      return(
        <Aa content={this.state.content} />
      )
    }
  }
}

const A1 = initContent(A);
const B1 = initContent(B)
ReactDOM.render(<div><B1></B1><A1></A1></div>, document.getElementById("root"));

若放开上面代码中的注释,那么包裹组件该方法原有的逻辑将被重写,可能会引起冲突。

二、约定:将不相关的props属性传递给包裹组件

render() {
  // 过滤掉与高阶函数功能相关的props属性,
  // 不再传递
  const { extraProp, ...passThroughProps } = this.props;

  // 向包裹组件注入props属性,一般都是高阶组件的state状态
  // 或实例方法
  const injectedProp = someStateOrInstanceMethod;

  // 向包裹组件传递props属性
  return (
    <WrappedComponent
      injectedProp={injectedProp}
      {...passThroughProps}
    />
  );
}

 

三、约定:最大使用组合

const ConnectedComment = connect(commentSelector, commentActions)(Comment);

等于下面


// connect是一个返回函数的函数(译者注:就是个高阶函数)
const enhance = connect(commentListSelector, commentListActions);
// 返回的函数就是一个高阶组件,该高阶组件返回一个与Redux store
// 关联起来的新组件
const ConnectedComment = enhance(CommentList);

这个有点类似于jq中的链式调用

四、约定:包装显示名字以便于调试

注意事项

一、不在render函数中使用高阶组件

简单来说react使用差异算法,当再render中使用高阶组件时,每次render返回的高阶组件都是新创建的,与原来的一定不一致,所以每次都要重新渲染,

这里产生的问题不仅仅是性能问题 —— 还有,重新加载一个组件会引起原有组件的所有状态和子组件丢失。

二、必须将静态方法做拷贝

   这里我只介绍一个方法

 

function enhance(WrappedComponent) {
  class Enhance extends React.Component {/*...*/}
  // 必须得知道要拷贝的方法 :(
  Enhance.staticMethod = WrappedComponent.staticMethod;
  return Enhance;
}

 

 

 

三、refs属性不能传递

 

参考:https://doc.react-china.org/docs/higher-order-components.html

转载于:https://www.cnblogs.com/zale-blogs/p/8615206.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值