利用ES6语法重构React组件与onclick的几种绑定方式(React.Component、React Refs中ref属性绑定任何组件)

一、创建组件

ES6 class创建的组件语法更加简明,也更符合javascript。内部的方法不需要使用function关键字。

React.Component(ES6)

import React,{ Component } from 'react';
class MyComponent extends Component {
 render() {
 return (
  <div>ES6方式创建的组件</div>
 );
 }
}
export default MyComponent;

(DVA)定义组件一般有三种方式:

// 1. 传统写法
const App = React.createClass({});
 
// 2. es6 的写法
class App extends React.Component({});
 
// 3. stateless 的写法(我们推荐的写法)
const App = (props) => ({});

其中第1种是我们(DVA)不推荐的写法,第2种是在你的组件涉及 react 的生命周期方法的时候采用这种写法,而第3种则是我们一般推荐的写法。

原文说明来自:http://www.jb51.net/article/112628.htm

二、属性

props propTypes and getDefaultProps

. 使用React.Component创建组件,需要通过在constructor中调用super()将props传递给React.Component 。另外react 0.13之后props必须是不可变的。

. 由于是用ES6 class语法创建组件,其内部只允许定义方法,而不能定义属性,class的属性只能定义在class之外。所以propTypes要写在组件外部。

. 对于之前的getDefaultProps方法,由于props不可变,所以现在被定义为一个属性,和propTypes一样,要定义在class外部。

React.Component(ES6)

import React,{ Component } from 'react';
class MyComponent extends Component {
 constructor(props) {
 super(props);
 }
  
 render() {
 return (
  <div>ES6方式创建的组件</div>
 );
 }
}
MyComponent.propTypes = {
 nameProp: React.PropTypes.string
};
MyComponent.defaultProps = {
 nameProp: ''
};
export default MyComponent;

三、状态this

. 使用ES6 class语法创建组件,初始化state的工作要在constructor中完成。不需要再调用getInitialState方法。这种语法更加的符合JavaScript语言习惯。

. 使用ES6 class语法创建组件, class中的方法不会自动将this绑定到实例中。必须使用 .bind(this)或者 箭头函数 =>来进行手动绑定。

React.Component(ES6)

import React,{ Component } from 'react';
class MyComponent extends Component {
 handleClick() {
 console.log(this);
 }
  
 render() {
 return (
  <div onClick={this.handleClick.bind(this)}>ES6方式创建的组件</div>
 );
 }
}
export default MyComponent;

也可以将绑定方法写到constructor中:

import React,{ Component } from 'react';
class MyComponent extends Component {
 constructor(props) {
 super(props);
 this.handleClick = this.handleClick.bind(this);
 }
 handleClick() {
 console.log(this);
 }
  
 render() {
 return (
  <div onClick={this.handleClick}>ES6方式创建的组件</div>
 );
 }
}
export default MyComponent;

或者使用箭头函数 => :

import React,{ Component } from 'react';
class MyComponent extends Component {
 handleClick = () => {
 console.log(this);
 }
  
 render() {
 return (
  <div onClick={this.handleClick}>ES6方式创建的组件</div>
 );
 }
}
export default MyComponent;

首先一起来回顾回顾React组件事件绑定的几种方式。

以onClick事件为例

1、最粗鲁的方式

class MyComponent extends Component {
 handleClick(e) {
     this.setState({
         key: 'value'
     })
 }
 render() {
     return (
         <div onClick={this.handleClick.bind(this)}></div>
     )
 }
}

直接把bind函数写到render方法里

2、较好的方式

class MyComponent extends Component {
 handleClick = e => {
     this.setState({
         key: 'value'
     })
 }
 render() {
     return (
         <div onClick={this.handleClick}></div>
     )
 }
}

使用ES7类属性箭头函数,自动绑定类作用域,需要transform-class-properties支持,缺点是该语法属于实验性质,并没有正式被划入标准,并且把类方法当作属性来用并不推荐。

3、最合理的方式

class MyComponent extends Component {
 constructor() {
     super()
     this.handleClick = this.handleClick.bind(this)
 }
 handleClick(e) {
     this.setState({
         key: 'value'
     })
 }
 render() {
     return (
         <div onClick={this.handleClick}></div>
     )
 }
}

把bind函数写入constructor方法中,仅当组件初始化时调用,绑定自身作用域,这是最合理的做法,缺点是组件中每增加一个新的事件,就要在constructor方法中绑定一次事件,编码起来相当麻烦。

原文来自:http://www.jianshu.com/p/4253b86b8ff8

五、Mixins

. 使用ES6语法来创建组件是不支持React mixins的,如果一定要使用React mixins就只能使用React.createClass方法来创建组件了。

 

原文说明来自:http://www.jb51.net/article/107193.htm

 

一:定义React组件

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

二:声明prop类型与默认prop

class Hello extends React.Component {
 // ...
}
Hello.propTypes = {
 value: React.PropTypes.string
};
Hello.defaultProps = {
 value: 'world'
};

三、设置初始state

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

四、自动绑定

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() {
  // Because `this.handleClick` is bound, we can use it as an event handler.
  return (
   <button onClick={this.handleClick}>
    Say hello
   </button>
  );
 }
}

原文来自:http://www.jb51.net/article/112885.htm

 

React Refs

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。

这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。

使用方法

绑定一个 ref 属性到 render 的返回值上:

<input ref="myInput" />

在其它代码中,通过 this.refs 获取支撑实例:

var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();

完整实例

你可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用,实例如下:

var MyComponent = React.createClass({
  handleClick: function() {
    // 使用原生的 DOM API 获取焦点
    this.refs.myInput.focus();
  },
  render: function() {
    //  当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
    return (
      <div>
        <input type="text" ref="myInput" />
        <input
          type="button"
          value="点我输入框获取焦点"
          onClick={this.handleClick}
        />
      </div>
    );
  }
});
 
ReactDOM.render(
  <MyComponent />,
  document.getElementById('example')

实例中,我们获取了输入框的支撑实例的引用,子点击按钮后输入框获取焦点。

我们也可以使用 getDOMNode()方法获取DOM元素

原文来自:http://www.runoob.com/react/react-refs.html

原文来自:https://segmentfault.com/a/1190000006259757

 

posted @ 2017-07-20 14:19  chenguiya  阅读(972)  评论(0)    收藏  举报