谈一谈创建React Component的几种方式
当我们谈起React的时候,多半会将注意力集中在组件之上,思考如何将页面划分成一个个组件,以及如何编写可复用的组件。但对于接触React不久,还没有真正用它做一个完整项目的人来说,理解如何创建一个组件也并不那么简单。在最开始的时候我以为创建组件只需要调用 几种方法1.createClass如果你还没有使用ES6语法,那么定义组件,只能使用 var React = require("react"); var Greeting = React.createClass({ propTypes: { name: React.PropTypes.string //属性校验 },getDefaultProps: function() { return { name: 'Mary' //默认属性值 }; },getInitialState: function() { return {count: this.props.initialCount}; //初始化state },handleClick: function() { //用户点击事件的处理函数 },render: function() { return <h1>Hello,{this.props.name}</h1>; } }); module.exports = Greeting; 这段代码,包含了组件的几个关键组成部分,这种方式下,组件的props、state等都是以对象属性的方式组合在一起,其中默认属props和初始state都是返回对象的函数,propTypes则是个对象。这里还有一个值得注意的事情是,在createClass中,React对属性中的所有函数都进行了 2.component因为ES6对类和继承有语法级别的支持,所以用ES6创建组件的方式更加优雅,下面是示例: import React from 'react'; class Greeting extends React.Component { constructor(props) { super(props); this.state = {count: props.initialCount}; this.handleClick = this.handleClick.bind(this); } //static defaultProps = { // name: 'Mary' //定义defaultprops的另一种方式 //} //static propTypes = { //name: React.PropTypes.string //} handleClick() { //点击事件的处理函数 } render() { return <h1>Hello,{this.props.name}</h1>; } } Greeting.propTypes = { name: React.PropTypes.string }; Greeting.defaultProps = { name: 'Mary' }; export default Greating; 可以看到Greeting继承自React.component,在构造函数中,通过super()来调用父类的构造函数,同时我们看到组件的state是通过在构造函数中对this.state进行赋值实现,而组件的props是在类Greeting上创建的属性,如果你对 用这种方式创建组件时,React并没有对内部的函数,进行this绑定,所以如果你想让函数在回调中保持正确的this,就要手动对需要的函数进行this绑定,如上面的handleClick,在构造函数中对this 进行了绑定。 3.PureComponet我们知道,当组件的props或者state发生变化的时候:React会对组件当前的Props和State分别与nextProps和nextState进行比较,当发现变化时,就会对 class CounterButton extends React.Component { constructor(props) { super(props); this.state = {count: 1}; } shouldComponentUpdate(nextProps,nextState) { if (this.props.color !== nextProps.color) { return true; } if (this.state.count !== nextState.count) { return true; } return false; } render() { return ( <button color={this.props.color} onClick={() => this.setState(state => ({count: state.count + 1}))}> Count: {this.state.count} </button> ); } }
class CounterButton extends React.PureComponent { constructor(props) { super(props); this.state = {count: 1}; } render() { return ( <button color={this.props.color} onClick={() => this.setState(state => ({count: state.count + 1}))}> Count: {this.state.count} </button> ); } } 大多数情况下, 我们使用 class ListOfWords extends React.PureComponent { render() { return <div>{this.props.words.join(',')}</div>; } } class WordAdder extends React.Component { constructor(props) { super(props); this.state = { words: ['marklar'] }; this.handleClick = this.handleClick.bind(this); } handleClick() { // 这个地方导致了bug const words = this.state.words; words.push('marklar'); this.setState({words: words}); } render() { return ( <div> <button onClick={this.handleClick} /> <ListOfWords words={this.state.words} /> </div> ); } } 这种情况下, 最简单避免上述情况的方式,就是避免使用可变对象作为props和state,取而代之的是每次返回一个全新的对象,如下通过 handleClick() { this.setState(prevState => ({ words: prevState.words.concat(['marklar']) })); } 你可以考虑使用 4.Stateless Functional Component上面我们提到的创建组件的方式,都是用来创建包含状态和用户交互的复杂组件,当组件本身只是用来展示,所有数据都是通过props传入的时候,我们便可以使用 import React from 'react'; const Button = ({ day,increment }) => { return ( <div> <button onClick={increment}>Today is {day}</button> </div> ) } Button.propTypes = { day: PropTypes.string.isRequired,increment: PropTypes.func.isRequired,} 这种组件,没有自身的状态,相同的props输入,必然会获得完全相同的组件展示。因为不需要关心组件的一些生命周期函数和渲染的钩子,所以不用继承自Component显得更简洁。 对比createClass vs Component对于 pureComponent vs Component通过上面对PureComponent和Component的介绍,你应该已经了解了二者的区别: Component vs Stateless Functional component
选哪个?这里仅列出一些参考:
参考文章optimizing-performance.html#shouldcomponentupdate-in-action (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |