React学习之进阶非ES6(十六)

前端之家收集整理的这篇文章主要介绍了React学习之进阶非ES6(十六)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

平时我们写React组件的时候一般就是直接用类组件

class Greeting extends React.Component {
  render() {
    return <h1>Hello,{this.props.name}</h1>;
  }
}

现在你可以不使用ES6的类语法,而用React.createClass函数进行处理

var Greeting = React.createClass({
  render: function() {
    return <h1>Hello,{this.props.name}</h1>;
  }
});

虽然上面的代码render这个函数基本和ES6语法的类组件没有多少区别,但是它们的区别个人认为还是比较大的。

1.PropTypes属性检测和defaultProps值区别

ES6语法

class Greeting extends React.Component {
  // ...
}

Greeting.propTypes = {
  name: React.PropTypes.string
};

Greeting.defaultProps = {
  name: 'Mary'
};

ES6语法

var Greeting = React.createClass({
  propTypes: {
    name: React.PropTypes.string
  },getDefaultProps: function() {
    return {
      name: 'Mary'
    };
  },// ...

});

对于propTypes大家还好理解,跟类组件基本一样,但是defaultProps却需要使用一个函数进行返回,这一点大家需要注意。

2.初始化this.state状态

ES6的语法非常简单,就是在construtor构造函数中直接对this.state赋值即可

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  // ...
}

而在非ES6中,我们要用函数getInitialState 函数进行初始化

var Counter = React.createClass({
  getInitialState: function() {
    return {count: this.props.initialCount};
  },// ...
});

3.自动绑定机制

React组件描述为类组件时,它的定义和ES6语法中类的定义语法是一模一样的,但是这有个非常尴尬的事情,就是内部的函数都不会绑定自我的实例,我们在前面也一直在constructor构造函数中用.bind(this)来绑定自身实例

class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
    // 必须加,代码实现绑定
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    alert(this.state.message);
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}

而用React.createClass创建的类则非常有意思,它帮你自动绑定了,不需要你用bind进行绑定。

var SayHello = React.createClass({
  getInitialState: function() {
    return {message: 'Hello!'};
  },handleClick: function() {
    alert(this.state.message);
  },render: function() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
});

如果你觉得上面的代码不够新鲜,那么新鲜得来了

class SayHello extends React.Component {
  constructor(props) {
    super(props);
    this.state = {message: 'Hello!'};
  }
  //这个语法够新鲜吧,简直是逆天了,用箭头函数和赋值来定义类内的函数
  //然而这个语法更像是个表达式赋值,而不是一个函数声明
  //所以如果不是为了装逼,请不要用这个语法
  handleClick = () => {
    alert(this.state.message);
  }
  render() {
    return (
      <button onClick={this.handleClick}>
        Say hello
      </button>
    );
  }
}

上面的代码注释中说了些话,主要是为了让大家警惕,上面的那个语法属于实验性质的,它最终有可能不会加入到ES语法中,所以最好不要用。

几点建议

  1. 如果你是用ES6语法的类组件,请在construcotr构造函数中使用bind函数进行绑定

  2. 如果你要用箭头函数的话,请在事件绑定中做onClick={(e) => this.handleClick(e)}

  3. 能用React.createClass()就用它

4.Mixins多继承模式

ES6没有推出多继承的语法,而React官方说很多代码库中都有使用Mixins将多个对象合并为一个对象,然而如果没有必要,它并不推荐你这么做

但是有时候允许你在React.createClass中使用mixins处理(createClass方法上实现了mixins多继承机制),比如说,我们可以将摧毁函数共用,用于最终组件摧毁时都会摧毁的资源,

var SetIntervalMixin = {
  componentWillMount: function() {
    this.intervals = [];
  },setInterval: function() {
    this.intervals.push(setInterval.apply(null,arguments));
  },componentWillUnmount: function() {
    this.intervals.forEach(clearInterval);
  }
};

var TickTock = React.createClass({
  mixins: [SetIntervalMixin],getInitialState: function() {
    return {seconds: 0};
  },componentDidMount: function() {
    this.setInterval(this.tick,1000);
  },tick: function() {
    this.setState({seconds: this.state.seconds + 1});
  },render: function() {
    return (
      <p>
        React has been running for {this.state.seconds} seconds.
      </p>
    );
  }
});

ReactDOM.render(
  <TickTock />,document.getElementById('example')
);

如下的代码即,createClass创建对象时,会将SetIntervalMixin对象的方法属性继承过来

mixins: [SetIntervalMixin]

使用mixins一定要确保最终将所有组件都摧毁了。

下一篇将讲React中不用JSX的痛

猜你在找的React相关文章