【译】React 组件的生命周期
github issue: https://github.com/chemdemo/c... 一段探索React自建内部构造的旅程在先前的文章里我们涵盖了React基本原理和如何构建更加复杂的交互组件。此篇文章我们将会继续探索React组件的特性,特别是生命周期。 稍微思考一下React组件所做的事,首先想到的是一点是:React描述了如何去渲染(DOM)。我们已经知道React使用 看起来我们需要对组件(运行)的各个阶段进行控制,组件运行所有涉及的各个阶段叫做组件的生命周期,并且每一个React组件都会经历这些阶段。React提供了一些方法并在组件处于相应的阶段时通知我们。这些方法叫做React组件的生命周期方法且会根据特定并可预测的顺序被调用。 基本上所有的React组件的生命周期方法都可以被分割成四个阶段:初始化、挂载阶段(mounting)、更新阶段、卸载阶段(unmounting)。让我们来近距离分别研究下各个阶段。 初始化阶段初始化阶段就是我们分别通过
现在我们来证明上面的猜想,实现一个显示的值可以被增加和减少的组件,基本上就是一个拥有“+”和“-”按钮的计数器。 var Counter = React.createClass({ getDefaultProps: function() { console.log('getDefaultProps'); return { title: 'Basic counter!!!' } },getInitialState: function() { console.log('getInitialState'); return { count: 0 } },render: function() { console.log('render'); return ( <div> <h1>{this.props.title}</h1> <div>{this.state.count}</div> <input type='button' value='+' onClick={this.handleIncrement} /> <input type='button' value='-' onClick={this.handleDecrement} /> </div> ); },handleIncrement: function() { var newCount = this.state.count + 1; this.setState({count: newCount}); },handleDecrement: function() { var newCount = this.state.count - 1; this.setState({count: newCount}); },propTypes: { title: React.PropTypes.string } }); ReactDOM.render( React.createElement(Counter),document.getElementById('app-container') ); 我们通过
现在我们想要让Counter组件可以设置 var Component = React.createClass({ getDefaultProps: function() { console.log('getDefaultProps'); return { title: "Basic counter!!!",step: 1 } },getInitialState: function() { console.log('getInitialState'); return { count: (this.props.initialCount || 0) }; },render: function() { console.log('render'); var step = this.props.step; return ( <div> <h1>{this.props.title}</h1> <div>{this.state.count}</div> <input type='button' value='+' onClick={this.updateCounter.bind(this,step)} /> <input type='button' value='-' onClick={this.updateCounter.bind(this,-step)} /> </div> ); },updateCounter: function(value) { var newCount = this.state.count + value; this.setState({count: newCount}); },propTypes: { title: React.PropTypes.string,initialCount: React.PropTypes.number,step: React.PropTypes.number } }); ReactDOM.render( React.createElement(Component,{initialCount: 5,step: 2}),document.getElementById('app-container') );
现在我们拥有了一个可定制化的组件。 增长(Mounting)阶段Mounting阶段发生在组件即将被插入到DOM之前。这个阶段有两个方法可以用:
getInitialState: function() {...},componentWillMount: function() { console.log('componentWillMount'); },
假设我们想要通过API拉取数据来初始化组件。我们应该直接在计数器组件的 var Container = React.createClass({ getInitialState: function() { return { data: null,fetching: false,error: null }; },render: function() { if (this.props.fetching) { return <div>Loading...</div>; } if (this.props.error) { return ( <div className='error'> {this.state.error.message} </div> ); } return <Counter {...data} /> },componentDidMount: function() { this.setState({fetching: true}); Axios.get(this.props.url).then(function(res) { this.setState({data: res.data,fetching: false}); }).catch(function(res) { this.setState({error: res.data,fetching: false}); }); } });
更新阶段当组件的属性或者状态更新时也需要一些方法来供我们执行代码,这些方法也是组件更新阶段的一部分且按照以下的顺序被调用: 1、当从父组件接收到新的属性时:
2、当通过
此阶段React组件已经被插入DOM了,因此这些方法将不会在首次render时被调用。 最先被调用的方法是 ... componentWillReceiveProps: function(newProps) { this.setState({count: newProps.initialCount}); },...
当有性能瓶颈时也可以使用 var TextComponent = React.createClass({ shouldComponentUpdate: function(nextProps,nextState) { if (this.props.text === nextProps.text) return false; return true; },render: function() { return <textarea value={this.props.text} />; } }); 此例中无论何时父组件传入一个“text”属性到 当接收到新的属性或者state时在render之前会立刻调用 ... componentWillUpdate: function(nextProps,nextState) { console.log('componentWillUpdate',nextProps,nextState); },...
这个方法的一个常见使用场景是当我们使用需要操作更新后的DOM才能工作的第三方库——如jQuery插件的时候。在 var Select2 = React.createClass({ componentDidMount: function() { $(this._ref).select2({data: this.props.items}); },render: function() { return ( <select ref={ function(input) { this._ref = input; }.bind(this) }> </select> ); },componentDidUpdate: function() { $(this._ref).select2('destroy'); $(this._ref).select2({data: this.props.items}); } }); 卸载阶段(unmounting)此阶段React只提供了一个方法:
它将在组件从DOM卸载之前被调用。可以在内部执行任何可能需要的清理工作,如无效的计数器或者清理一些在 ... componetWillUnmount: function(){ $(this._ref).select2('destroy'); },... 概述React为我们提供了一种在创建组件时申明一些将会在组件生命周期的特定时机被自动调用的方法的可能。现在我们很清晰的理解了每一个组件生命周期方法所扮演的角色以及他们被调用的顺序。这使我们有机会在组件创建和销毁时执行一些操作。也允许我们在当属性和状态变化时做出相应的反应从而更容易的整合第三方库和追踪性能问题。 希望您觉得此文对您有用,如果是这样,请推荐之!!! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |