We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React 在触发更新的时候执行的主要源码
精简主要代码如下:
updateComponent: function( transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext ) { var inst = this._instance; var willReceive = false; var nextContext; //省略 var prevProps = prevParentElement.props; var nextProps = nextParentElement.props; //如果是 props 发生更新,而不是 state 的简单更新 if (prevParentElement !== nextParentElement) { willReceive = true; } //如果是 props 更新,则触发 componentWillReceiveProps() if (willReceive && inst.componentWillReceiveProps) { if (__DEV__) { measureLifeCyclePerf( () => inst.componentWillReceiveProps(nextProps, nextContext), this._debugID, 'componentWillReceiveProps', ); } else { inst.componentWillReceiveProps(nextProps, nextContext); } } var nextState = this._processPendingState(nextProps, nextContext); var shouldUpdate = true; if (!this._pendingForceUpdate) { if (inst.shouldComponentUpdate) { //如果组件实例有 shouldComponentUpdate 则调用 shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext); } else { //如果使用了 PureComponent if (this._compositeType === CompositeTypes.PureClass) { shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState); } } } this._updateBatchNumber = null; if (shouldUpdate) { //执行更新操作 this._performComponentUpdate( nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext ); } else { this._currentElement = nextParentElement; this._context = nextUnmaskedContext; inst.props = nextProps; inst.state = nextState; inst.context = nextContext; } },
在这个函数里,主要是判断是 state 还是 props 引起的变化,如果是 props,则执行实例的 componentWillReceiveProps() ,然后再判断实例是否提供了 shouldComponentUpdate 方法,如果提供,则直接调用,否则再判断是否使用了 PureComponent, 如果使用了,则使用浅比较来判断是否更新。 当前面两者都不满足,则执行 performComponentUpdate。
继续追踪代码,会发现 performComponentUpdate 里面调用了 _updateRenderdComponent ,源码如下:
_performComponentUpdate: function( nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext ) { var inst = this._instance; var hasComponentDidUpdate = Boolean(inst.componentDidUpdate); var prevProps; var prevState; var prevContext; if (hasComponentDidUpdate) { prevProps = inst.props; prevState = inst.state; prevContext = inst.context; } if (inst.componentWillUpdate) { inst.componentWillUpdate(nextProps, nextState, nextContext); } } this._currentElement = nextElement; this._context = unmaskedContext; inst.props = nextProps; inst.state = nextState; inst.context = nextContext; if (inst.unstable_handleError) { this._updateRenderedComponentWithErrorHandling(transaction, unmaskedContext); } else { this._updateRenderedComponent(transaction, unmaskedContext); } if (hasComponentDidUpdate) { if (__DEV__) { transaction.getReactMountReady().enqueue(() => { measureLifeCyclePerf( inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), this._debugID, 'componentDidUpdate' ); }); } else { transaction.getReactMountReady().enqueue( inst.componentDidUpdate.bind(inst, prevProps, prevState, prevContext), inst ); } } },
_updateRenderedComponent 里又调用了 _updateRenderedComponentWithNextElement ,_updateRenderedComponentWithNextElement 里面 又通过 shouldUpdateReactComponent 来判断组件是否需要更新:
_updateRenderedComponentWithNextElement: function( transaction, context, nextRenderedElement, safely ) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { ReactReconciler.receiveComponent( prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context) ); } else { var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance); ReactReconciler.unmountComponent( prevComponentInstance, safely, false /* skipLifecycle */ ); var nodeType = ReactNodeTypes.getType(nextRenderedElement); this._renderedNodeType = nodeType; var child = this._instantiateReactComponent( nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ ); this._renderedComponent = child; var nextMarkup = ReactReconciler.mountComponent( child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context), debugID ); this._replaceNodeWithMarkup( oldHostNode, nextMarkup, prevComponentInstance ); } },
shouldUpdateReactComponent 的源码 如下:
function shouldUpdateReactComponent(prevElement, nextElement) { var prevEmpty = prevElement === null || prevElement === false; var nextEmpty = nextElement === null || nextElement === false; if (prevEmpty || nextEmpty) { return prevEmpty === nextEmpty; } var prevType = typeof prevElement; var nextType = typeof nextElement; if (prevType === 'string' || prevType === 'number') { return (nextType === 'string' || nextType === 'number'); } else { return ( nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key ); } }
由此发现 React.Component 在这里使用了深比较, 然后之后的更新流程就是使用 diff 算法来比较两次的 Virtual DOM 是否改变从而执行更新操作。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
React 在触发更新的时候执行的主要源码
精简主要代码如下:
在这个函数里,主要是判断是 state 还是 props 引起的变化,如果是 props,则执行实例的 componentWillReceiveProps() ,然后再判断实例是否提供了 shouldComponentUpdate 方法,如果提供,则直接调用,否则再判断是否使用了 PureComponent, 如果使用了,则使用浅比较来判断是否更新。 当前面两者都不满足,则执行 performComponentUpdate。
继续追踪代码,会发现 performComponentUpdate 里面调用了 _updateRenderdComponent ,源码如下:
_updateRenderedComponent 里又调用了 _updateRenderedComponentWithNextElement ,_updateRenderedComponentWithNextElement 里面 又通过 shouldUpdateReactComponent
来判断组件是否需要更新:
shouldUpdateReactComponent 的源码
如下:
由此发现 React.Component 在这里使用了深比较, 然后之后的更新流程就是使用 diff 算法来比较两次的 Virtual DOM 是否改变从而执行更新操作。
The text was updated successfully, but these errors were encountered: