定而后能静,静而后能安,安而后 能虑,虑而后能得,物有本末,事 有始终,所知先后,则近道亦。---《大学》
从表象上来看,react的旧版本0.3stable的生命周期可以在ReactCompositeComponent.js中找到,该文件定义了一个复合组件接口,该接口中声明了组件的生命周期及其他一些常用方法,生命周期函数的作用在注释中描述的非常清楚
react中复合组件 的注释描述
/**
* Composite components are higher-level components that compose other composite
* or native components.
*
* To create a new type of `ReactCompositeComponent`, pass a specification of
* your new class to `React.createClass`. The only requirement of your class
* specification is that you implement a `render` method.
*
* var MyComponent = React.createClass({
* render: function() {
* return
Hello World
;
* }
* });
*
* The class specification supports a specific protocol of methods that have
* special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for
* more the comprehensive protocol. Any other properties and methods in the
* class specification will available on the prototype.
*
* @interface ReactCompositeComponentInterface
* @internal
*/
ReactCompositeComponentInterface 复合组件接口
var ReactCompositeComponentInterface = {
props:SpecPolicy.DDFINE_ONCE,
/**
* Invoked once before the component is mounted. The return value will be used
* as the initial value of `this.state`.
*
* getInitialState: function() {
* return {
* isOn: false,
* fooBaz: new BazFoo()
* }
* }
*
* @return {object}
* @optional
*/
getInitialState:
/**
* Uses props from `this.props` and state from `this.state` to render the
* structure of the component.
*
* No guarantees are made about when or how often this method is invoked, so
* it must not have side effects.
*
* render: function() {
* var name = this.props.name;
* return
Hello, {name}!
;
* }
*
* @return {ReactComponent}
* @nosideeffects
* @required
*/
render:
/**
* Invoked when the component is initially created and about to be mounted.
* This may have side effects, but any external subscriptions or data created
* by this method must be cleaned up in `componentWillUnmount`.
*
* @optional
*/
componentWillMount:
/**
* Invoked when the component has been mounted and has a DOM representation.
* However, there is no guarantee that the DOM node is in the document.
*
* Use this as an opportunity to operate on the DOM when the component has
* been mounted (initialized and rendered) for the first time.
*
* @param {DOMElement} rootNode DOM element representing the component.
* @optional
*/
componentDidMount:
/**
* Invoked before the component receives new props.
*
* Use this as an opportunity to react to a prop transition by updating the
* state using `this.setState`. Current props are accessed via `this.props`.
*
* componentWillReceiveProps: function(nextProps) {
* this.setState({
* likesIncreasing: nextProps.likeCount > this.props.likeCount
* });
* }
*
* NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
* transition may cause a state change, but the opposite is not true. If you
* need it, you are probably looking for `componentWillUpdate`.
*
* @param {object} nextProps
* @optional
*/
componentWillReceiveProps:
/**
* Invoked while deciding if the component should be updated as a result of
* receiving new props and state.
*
* Use this as an opportunity to `return false` when you're certain that the
* transition to the new props and state will not require a component update.
*
* shouldComponentUpdate: function(nextProps, nextState) {
* return !equal(nextProps, this.props) || !equal(nextState, this.state);
* }
*
* @param {object} nextProps
* @param {?object} nextState
* @return {boolean} True if the component should update.
* @optional
*/
shouldComponentUpdate:
/**
* Invoked when the component is about to update due to a transition from
* `this.props` and `this.state` to `nextProps` and `nextState`.
*
* Use this as an opportunity to perform preparation before an update occurs.
*
* NOTE: You **cannot** use `this.setState()` in this method.
*
* @param {object} nextProps
* @param {?object} nextState
* @param {ReactReconcileTransaction} transaction
* @optional
*/
componentWillUpdate:
/**
* Invoked when the component's DOM representation has been updated.
*
* Use this as an opportunity to operate on the DOM when the component has
* been updated.
*
* @param {object} prevProps
* @param {?object} prevState
* @param {DOMElement} rootNode DOM element representing the component.
* @optional
*/
componentDidUpdate:
/**
* Invoked when the component is about to be removed from its parent and have
* its DOM representation destroyed.
*
* Use this as an opportunity to deallocate any external resources.
*
* NOTE: There is no `componentDidUnmount` since your component will have been
* destroyed by that point.
*
* @optional
*/
componentWillUnmount:
updateComponent:
}
生命周期函数 注释解释
getInitialState(): 组件加载之前调用一次,其返回值将作为this.state的初始值。
render(): 从this.props 或 this.state中获取值去渲染组件结构
componentWillMount(): 在组件最初创建并即将加载时调用。这可能会有副作用,但任何外部订阅或数据必须在“componentWillUnmount”中清除
componentDidMount(): 在组件加载完成并且有确定的DOM呈现时触发,但是不保证DOM节点已经插入到Document中。
componentWillReceiveProps(): 在组件接受到新的props时触发。通常在此时通过setState更新组件状态
shouldComponentUpdate(): 当组件接收到新的props或state时决定是否更新组件,
componentWillUpdate(): 组件即将更新时触发,此方法中不能调用this.setState()
componentDidUpate(): 组件的Dom更新后触发
componentWillUnmount(): 当组件即将从父组件移除或自身Dom销毁时触发
除了ReactCompositeComponentInterface接口中定义的生命周期以外
ReactCompositeComponent.js中还定义了ReactCompositeComponentMixin
对象,用来处理组件的加载 ,更新,卸载等逻辑
var ReactCompositeComponentMixin = {
// 组件基本构造
construct:function(){}
}
// 加载逻辑
mountComponent():function(){}
// 卸载逻辑
unmountComponent():function(){}
// 接受props逻辑
receiveProps:function(){}
// 设置状态
setState:function(){}
// replaceState
replaceState:function(){}
// _receivePropsAndState
_receivePropsAndState:function(){}
// 将接受到的props及state新值merge,通知更新方法
_performComponentUpdate:function(){}
// 更新Dom展示
updateComponent:functinon(){}
然后通过MIX将其他逻辑都加入ReactCompositeComponentBase
的实例上
var ReactCompositeComponentBase = function() {};
mixInto(ReactCompositeComponentBase, ReactComponent.Mixin);
mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
最后定义复合组件并将其导出
var ReactCompositeComponent = {
LifeCycle: CompositeLifeCycle,
Base: ReactCompositeComponentBase,
/**
* Creates a composite component class given a class specification.
*
* @param {object} spec Class specification (which must define `render`).
* @return {function} Component constructor function.
* @public
*/
createClass: function(spec) {
var Constructor = function(initialProps, children) {
this.construct(initialProps, children);
};
Constructor.prototype = new ReactCompositeComponentBase();
Constructor.prototype.constructor = Constructor;
mixSpecIntoComponent(Constructor, spec);
invariant(
Constructor.prototype.render,
'createClass(...): Class specification must implement a `render` method.'
);
var ConvenienceConstructor = function(props, children) {
return new Constructor(props, children);
};
ConvenienceConstructor.componentConstructor = Constructor;
ConvenienceConstructor.originalSpec = spec;
return ConvenienceConstructor;
},
/**
* Marks the provided method to be automatically bound to the component.
* This means the method's context will always be the component.
*
* React.createClass({
* handleClick: React.autoBind(function() {
* this.setState({jumping: true});
* }),
* render: function() {
* return Jump;
* }
* });
*
* @param {function} method Method to be bound.
* @public
*/
autoBind: function(method) {
function unbound() {
invariant(
false,
'React.autoBind(...): Attempted to invoke an auto-bound method that ' +
'was not correctly defined on the class specification.'
);
}
unbound.__reactAutoBind = method;
return unbound;
}
};
module.exports = ReactCompositeComponent;
感悟
源码这个东西感觉还是需要去看的,虽然有可能我们看一遍看不明白,但是多看几遍,多去思考几个问题,还是会有收获的,虽然我们不一定非得要去实现一个跟它一模一样的框架,但是源码中一些比较好的写代码的思想,我们是完全可以借鉴过来的。
最后说两句
- 动一动您的小手,
「点个赞吧」
- 都看到这里了,不妨
「加个关注」
![1389d9d6aee8dc90e556a276ef305337.png](https://i-blog.csdnimg.cn/blog_migrate/e1d0cb1e66f826245964ab23d307e5a5.jpeg)