±à¼ÍƼö: |
±¾ÎÄÖ÷ÒªÔ´Âë·ÖÎö°üº¬£ºReact¡¢Preact£¬½Ó×Å˵Ã÷ÁËPreactºÍReactÏà֮ͬ´¦ºÍ²»Í¬Ö®´¦¡£
±¾ÎÄÀ´×ÔÓÚ²©¿ÍÔ°,ÓÉ»ðÁú¹ûÈí¼þAnna±à¼ÍƼö¡£ |
|
PreactÊÇReactµÄÇáÁ¿¼¶ÊµÏÖ£¬ÊÇReact±È½ÏºÃµÄÌæ´úÕßÖ®Ò»£¬ÓÐ×ÅÌå»ýСµÄÓŵ㣬µ±È»ÓëReactÖ®¼äÒ»¶¨»á´æÔÚʵÏÖÉϵIJîÒ죬±¾ÎĽéÉÜÁËÔÚ
setState ·½ÃæµÄ²îÒìÖ®´¦¡£
Ô´Âë·ÖÎö
Ê×ÏÈÀ´·ÖÎöÏÂReactÒÔ¼°PreactÔÚsetState²¿·ÖµÄ¾ßÌåʵÏÖ¡£
(Ì«³¤²»¿´Ïë͵ÀÁ£¬¿ÉÒÔÖ±½ÓÏ·¿´½áÂÛ)
React
¹Ø¼ü´úÂ룺
setState ½×¶Î£º
// ReactUpdateQueue.js
enqueueSetState: function(publicInstance, partialState)
{
...
var queue =
internalInstance._pendingStateQueue ||
(internalInstance._pendingStateQueue = []);
queue.push(partialState);
enqueueUpdate(internalInstance);
} |
¿ÉÒÔ¿´µ½ReactÔÚ setState µÄʱºò²»»á×öÈκδ¦Àí£¬»á°Ñ±ä¸üÖ±½Ó·Åµ½Ò»¸öרÃÅ´¦Àí state
µÄ¶ÓÁÐÀ﹩×é¼þ¸üÐÂʱʹÓá£
¸üн׶Σº
// ReactCompositeComponent.js
updateComponent: function(
transaction,
prevParentElement,
nextParentElement,
prevUnmaskedContext,
nextUnmaskedContext,
) {
var inst = this._instance;
...
var willReceive = false;
var nextContext;
if (this._context === nextUnmaskedContext)
{
nextContext = inst.context;
} else {
nextContext = this._processContext (nextUnmaskedContext);
willReceive = true;
}
var prevProps = prevParentElement.props;
var nextProps = nextParentElement.props;
if (prevParentElement !== nextParentElement)
{
willReceive = true;
}
if (willReceive && inst.componentWillReceiveProps)
{
...
inst.componentWillReceiveProps (nextProps, nextContext);
}
// ÔÚ´Ë´¦²Å¼ÆËã nextState
var nextState = this._processPendingState (nextProps,
nextContext); // ´Ë´¦´«ÈëÁË nextProps
var shouldUpdate = true;
if (!this._pendingForceUpdate) {
if (inst.shouldComponentUpdate) {
...
shouldUpdate = inst.shouldComponentUpdate(
nextProps,
nextState,
nextContext,
);
} else {
if (this._compositeType === CompositeTypes.PureClass)
{ // Çúڰ壬֪ʶµã ¡ª¡ª Èç¹ûÄãµÄ×é¼þûʵÏÖshouldComponentUpdate£¬ÄÇô°ÑReact.Component
»»³É React.PureComponent ¿ÉÒÔ»ñµÃ»ù´¡°æÓÅ»¯£¬Ìá¸ßÐÔÄÜ¡£
shouldUpdate =
!shallowEqual(prevProps, nextProps) ||
!shallowEqual(inst.state, nextState); // dz±È½Ï£¬¿ÉÒԳȥ×Ô¼º¸Ä³ÉÊôÐÔºÚ/°×Ãûµ¥°æ
}
}
}
...
}
// ReactCompositeComponent.js
_processPendingState: function(props, context)
{ // props: nextProps
var inst = this._instance;
var queue = this._pendingStateQueue;
var replace = this._pendingReplaceState;
this._pendingReplaceState = false;
this._pendingStateQueue = null;
if (!queue) {
return inst.state;
}
if (replace && queue.length === 1)
{
return queue[0];
}
var nextState = Object.assign({}, replace
? queue[0] : inst.state);
for (var i = replace ? 1 : 0; i < queue.length;
i++) {
var partial = queue[i];
Object.assign(
nextState,
typeof partial === 'function'
? partial.call (inst, nextState, props, context)
// nextProps
: partial,
);
}
return nextState;
}
|
ͨ¹ýÉÏÃæ×é¼þ¸üеÄÁ÷³Ì´úÂë¿ÉÒÔ¿´µ½£º
ÔÚ updateComponent ÖУ¬ÔÚ componentWillReceiveProps Ö®ºó²Å»á¼ÆËã
nextState£¬ËùÒÔÔÚ componentWillReceiveProps ÖÐ setState
ÊÇ¿ÉÒÔÔÚµ±´Î¸üÐÂÖÐÉúЧµÄ¡£
ÔÚ _processPendingState »á¶Ô¶ÓÁÐÀïµÄ state ½øÐеþ¼Ó£¬Èç¹ûÐÞ¸ÄÊǺ¯Êý·½Ê½£¬´Ë´¦´«ÈëµÄstate²ÎÊýÊÇ
nextState£¬props ÊÇ nextProps¡£
Preact
¹Ø¼ü´úÂ룺
setState ½×¶Î£º
// component.js
setState(state, callback) {
let s = this.state;
if (!this.prevState) this.prevState = extend({},
s);
extend(s, typeof state==='function' ? state(s,
this.props) : state);
if (callback) (this._renderCallbacks = (this._renderCallbacks
|| [])).push(callback);
enqueueRender(this);
} |
ʵÏֵļòµ¥´Ö±©£¬ÔÚ setState µÄʱºò¾Í½øÐÐÁ˺ϲ¢£¬»áÁ¢¼´¸Äд this.state£¬ÔÚµÚÒ»´Î
setState ʱ»á±£Áô state ״̬µ½ prevState¡£ÓÉÓÚÊÇÁ¢¼´ºÏ²¢state£¬Èç¹ûÈë²ÎstateÊǺ¯Êý£¬props
½«Ö»Êǵ±Ç° this.props¡£
¸üн׶Σº
export function
renderComponent (component, opts, mountAll, isChild)
{
...
previousProps = component.prevProps || props,
previousState = component.prevState || state,
previousContext = component.prevContext || context,
...
// if updating
if (isUpdate) {
component.props = previousProps;
component.state = previousState;
component.context = previousContext;
if (opts!==FORCE_RENDER
&& component.shouldComponentUpdate
&& component.shouldComponentUpdate (props,
state, context) === false) {
skip = true;
}
else if (component.componentWillUpdate) {
component.componentWillUpdate (props, state,
context);
}
component.props = props;
component.state = state;
component.context = context;
}
...
} |
ÔÚ¸üÐÂÁ÷³ÌǰÌáÈ¡ÁË¾É state£¬shouldComponentUpdate¡¢componentWillUpdate
Ö®ºó»¹Ô»ØÐÂÖµ£¬ËùÒÔÔÚ shouldComponentUpdate ÉúÃüÖÜÆÚÖУ¬this.props
½«»ñÈ¡µÄÊÇ prevProps£¬ÕâÀïÓë React µÄÂß¼²¢²»Ò»Ö¡£
»®Öصã
Ïàͬµã£º
ÔÚ componentWillReceiveProps ÖÐ setState ¶¼»áÓ¦Óõ½ nextState¡£
ÔÚ shouldComponentUpdate ÖÐ setState ¶¼²»»áÓ¦Óõ½ nextState£¬µ«ÊÇ¿ÉÒÔÖ±½Ó²Ù×÷´«ÈëµÄ
nextState¡£
²»Í¬µã£º
ReactÏ setState µÄÖµ²»»áÁ¢¼´ÉúЧ£¬»áÒ»Ö±»ýÀÛµ½ componentWillReceiveProps£¬ÔÚ´ËÖ®ºó»á½øÐкϲ¢£¬²¢Ìṩ¸øºóÐøÉúÃüÖÜÆÚ¡£¶øPreactÏÂ
setState »áÁ¢¼´·´Ó³µ½ this.state£¬µ«ÊÇ£¬ÔÚ¸üÐÂ×é¼þµÄÉúÃüÖÜÆÚµ½ render ǰ(eg:
shouldComponentUpdate), this.state ½«»áÊÇ prevState¡£
shouldComponentUpdate ½×¶Î setState ËäÈ»²»»áÓ°Ïìµ½×îÖÕ state
µÄÖµ£¬µ«ÊÇPreactÏ»áÓ°Ïì this.state µÄÖµ£¬±ÈÈçÖ®ºó componentWillUpdate
ÖÐµÄ this.state, ×ÜÖ®´Ë½×¶Î²»Òª setState ·´ÕýҲûÓá£
setState Èç¹ûʹÓú¯ÊýÐ޸ģ¬PreactÏ´«ÈëµÄ props ½«»áÊÇ prevProps£¬¶øReactÖÐÊÇ
nextProps£¬ÔÚ componentWillReceiveProps ÖÐ setState ʱҪעÒâ¡£
×ܽá
Èç¹ûÄãдµÄ¹¤³ÌÐèҪͬʱ¼æÈÝReact¼°PreactµÄ»°£º
²»ÒªÀûÓÃReactÏ setState ÔÚͬһ´Î×é¼þ¸üÐÂÖ´ÐÐǰ state ²»Á¢¼´¸üеÄÌØÐÔ£¬×¢Òâ¶à¸ö
setState Ö®¼äÊÇ·ñÓ°Ï죬±ØÒªÊ±ÊÖ¶¯±£´æ¾ÉÖµ¡£
ÔÚ×é¼þ¸üÐÂÉúÃüÖÜÆÚÄÚ,³ý componentWillReceiveProps Ö®ÍⲻҪʹÓà setState£¬ÌṩÁË
nextState µÄÉúÃüÖÜÆÚ£¬¿ÉÒÔÖ±½ÓÐÞ¸Ä nextState¡£
¾¡Á¿±ÜÃâʹÓà setState º¯ÊýÐ޸ķ½Ê½£¬ÔÚ componentWillReceiveProps
ÖÐʹÓÃʱ£¬Ê¹ÓÃÉúÃüÖÜÆÚÖÐµÄ prevProps(this.props) ºÍ nextProps¡£
p.s: antd-mobile 2.0Õýʽ°æÒÑ·¢²¼£¬Í¬Ê±¼æÈÝreact¡¢preact£¬ÇáÁ¿¡¢¿ìËÙ¡¢Ò×ÓõÄÒÆ¶¯¶Ë×é¼þ¿â£¬µÈÄãÀ´ÓÃ
|