利用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
浙公网安备 33010602011771号