创建 React 组件三种“姿势”

栏目: IOS · Android · 发布时间: 7年前

内容简介:React 世界中,组成一个页面的最小单元为一个个组件,很显然如何合理的创建它们是个非常关键的点。下面介绍一下我对三种创建组件方式的理解与总结。了解过 React 的人都知道,一个 Component 数据源有两个:当函数式的创建一个组件之后,显然它已经注定了没法再拥有自己的 State 了,只能 “无脑” 的去获取属性内容并展示,因为函数式组件其实是一个只实现了 render 函数的组件。

React 世界中,组成一个页面的最小单元为一个个组件,很显然如何合理的创建它们是个非常关键的点。下面介绍一下我对三种创建组件方式的理解与总结。

从简单开始:函数式组件

了解过 React 的人都知道,一个 Component 数据源有两个:

  1. 来自外部的属性(props)
  2. 来自内部的状态(State)

当函数式的创建一个组件之后,显然它已经注定了没法再拥有自己的 State 了,只能 “无脑” 的去获取属性内容并展示,因为函数式组件其实是一个只实现了 render 函数的组件。

所以把这种组件称之为 “小傻瓜组件” 非常的形象

创建 React 组件三种“姿势”

一个 “傻瓜函数式组件” 的例子:

// 这一句导入必须添加, JSX 语境依赖于此
import React from 'react';

export default ({order="没人下达命令,我就啥也不干"}) => {
    return (
        <div>
            我是“傻瓜组件”,我完全服从命令:{order}.
        </div>
    );
};
复制代码

这个简单的组件只接受一个 order 的 ,并且为这个属性设置了一个默认值。

  1. 当使用这个组件的地方为它设置了 order 属性,就会打印外部设置的order属性值;
  2. 如果没有设置,就会打印这个默认值(ES6 语法允许给定义的函数参数设置一个默认值)

这里使用了 ES6 箭头语法,快速的创建了一个无状态的函数式组件并 exoprt 出去供外界使用。

复杂点的:继承 React Component 相关类实现

React 版本16以后,官方已经不推荐使用 createclass 的方式创建组件了,同时也取消了以前 Mixin 那一套侵入式复用代码的做法,转而推荐大家使用高阶函数的方式来实现对代码的复用

继承的方式创建一个组件可以继承两个父类:

  1. React.Component
  2. React.PureComponent

PureComponent 和 Component 除了在 shouldComponentUpdate 方法的实现逻辑上不一样,其他表现都一样,PureComponent使用了props和state的浅比较。

一般情况下我们选择继承 React.PureComponent 可以优化我们的组件性能,不过特殊时候你也可以选择继承 React.Component,然后自己去实现 shouldComponentUpdate 方法的逻辑部分。

相比“傻瓜式”组件,继承方式获得的组件更加 “聪明” 了:

1.它可以有自己的属性 2.它可以有自己的状态 3.它可以有自己的生命周期逻辑

创建 React 组件三种“姿势”

一个简单的 “聪明的” 继承式的组件例子:

import React from "react";
import PropTypes from "prop-types";

export default class ComponentOne extends React.PureComponent {
  static defaultProps = {
    propOne: "默认属性"
  };

  static propTypes = {
    propOne: PropTypes.string.isRequired
  };

  constructor(props) {
    super(props);
    console.log("构造函数");
    this.clickToAdd = this.clickToAdd.bind(this);
    this.state = {
      count: 0
    };
  }

  clickToAdd() {
    this.setState({
      count: this.state.count + 1
    });
  }

  componentDidMount() {
    console.log("界面装载完成");
  }

  render() {
    return (
      <div>
          <div>
          我是由继承 React.PureComponent 创建的组件。并且我有属性:{this.props.propOne}
          </div>
          <div>
              当前计数:{this.state.count}
          </div>
          <div>
              <button onClick={this.clickToAdd}>点击计数增加</button>
          </div>
      </div>
    );
  }
}
复制代码

需要注意的一点,使用继承的方式创建的组件,它的成员函数都不会自动绑定 this,推荐在构造函数 constructor 中进行手动 bind。

上面代码中的组件有自己的状态,有自己的属性,也自己实现了生命周期函数中的 componentDidMount,在里面简单打印了一句 log。

更厉害的:高阶组件 HOC(Higher Order Component)

高阶组件,我的理解就是一个能接受组件为参数,并能返回一个新组件的函数。高阶组件有下面两种实现方式:

1. 代理模式(组合)

先看示例代码:

import React from 'react';

const agent = (WrappedComponent, newProps) => {
    return class WrappingComponent extends React.PureComponent{
        render(){
            return <WrappedComponent {...this.props} {...newProps}/>
        }
    }
}

export default agent;
复制代码

WrappingComponent 和 WrappedComponent 都分别走一遍自己的生命周期,代理模式下的高阶函数是两个组件的一个组合。

可以用此来操纵传入的 props,达到复用代码的目的。

2. 继承模式(继承)

先看示例代码:

import React from 'react';

const OnlyForLoginComponent = (WrappedComponent) => {
    return class WrappingComponent extends WrappedComponent{
        render(){
            if (this.props.logined) {
                return super.render();
            } else {
                return (
                    <div>
                        请先登录。
                    </div>
                );
            }
        }
    }
}

export default OnlyForLoginComponent;
复制代码

可以看到这里通过继承的方式实现了一个新的组件并返回。采用继承的方式实现的高阶组件,是一种合二为一的方式,因此我们可以操纵 WrappedComponent 的生命周期,当然也可以操纵它的属性。

比如上面的代码展示的就是,使用高阶组件生成了一个登录状态判断的状态组件,如果登录了就继续渲染 super(也就是 WrappedComponent),否则就提示“请先登录”。

熟悉 React-Redux 库的同学可以探索一下它的 connect 函数,这个函数的返回值就是一个高阶组件,它接受一个组件并返回一个新组件。

到此,三种主流的创建新组件的方式已经总结完毕,这些内容也是我自己在学习实践过程中的一些总结,写下来分享给大家,希望共同进步。

创建 React 组件三种“姿势”

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。

Beginning XML with DOM and Ajax

Beginning XML with DOM and Ajax

Sas Jacobs / Apress / 2006-06-05 / USD 39.99

Don't waste time on 1,000-page tomes full of syntax; this book is all you need to get ahead in XML development. Renowned web developer Sas Jacobs presents an essential guide to XML. Beginning XML with......一起来看看 《Beginning XML with DOM and Ajax》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换