Heim >Web-Frontend >js-Tutorial >Der Unterschied zwischen setState in React und Preact
Preact ist eine einfache Implementierung von React und eine der besseren Alternativen zu React. Es gibt natürlich Unterschiede in der Implementierung zwischen ihm und React.
Lassen Sie uns zunächst die spezifische Implementierung des setState-Teils von React und Preact analysieren.
(Es ist zu lang und Sie möchten faul sein, Sie können einfach nach unten scrollen und die Schlussfolgerung lesen)
Tastencode:
// ReactUpdateQueue.jsenqueueSetState: function(publicInstance, partialState) { ... var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []); queue.push(partialState); enqueueUpdate(internalInstance);}
Sie können sehen, dass React bei setState keine Verarbeitung durchführt und die Änderungen direkt in eine Warteschlange speziell für den Verarbeitungsstatus zur Verwendung bei Komponenten stellt werden aktualisiert.
// ReactCompositeComponent.jsupdateComponent: 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); // 浅比较,可以抄去自己改成属性黑/白名单版 } } } ...}// 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;}
Sie können den Prozesscode der oben genannten Komponentenaktualisierung durchsehen:
In updateComponent wird nextState nach ComponentWillReceiveProps berechnet, sodass setState in ComponentWillReceiveProps im aktuellen Update wirksam werden kann.
In _processPendingState wird der Status in der Warteschlange überlagert. Wenn sich die Änderung im Funktionsmodus befindet, ist der hier übergebene Statusparameter nextState und die Requisiten sind nextProps.
Schlüsselcode:
// component.jssetState(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);}
Implementierung Es ist einfach und grob. Es wird während setState zusammengeführt und this.state wird sofort neu geschrieben. Wenn setState zum ersten Mal festgelegt wird, bleibt der Status in prevState erhalten. Da der Status sofort zusammengeführt wird und der Eingabeparameter state eine Funktion ist, sind die Requisiten die aktuellen 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; } ...}
Der alte Zustand wird vor dem Aktualisierungsprozess extrahiert und sollte danachComponentUpdate und ComponentWillUpdate auf den neuen Wert zurücksetzen. Daher erhält this.props im Lebenszyklus von ShouldComponentUpdate prevProps, was nicht mit der Logik von React vereinbar ist.
Gleicher Punkt:
setState in ComponentWillReceiveProps wird auf nextState angewendet.
setState in ShouldComponentUpdate wird nicht auf nextState angewendet, aber der eingehende nextState kann direkt manipuliert werden.
Unterschied:
Der Wert von setState unter React wird nicht sofort wirksam, sondern akkumuliert bis ComponentWillReceiveProps und wird dann zusammengeführt . Und stellen Sie es für nachfolgende Lebenszyklen bereit. Unter Preact wird setState sofort in this.state widergespiegelt, aber , bevor der Lebenszyklus der Komponente zum Rendern aktualisiert wird (z. B. ShouldComponentUpdate), wird this.state prevState sein.
Obwohl setState in der Phase „shouldComponentUpdate“ keinen Einfluss auf den Wert des Endzustands hat, wirkt es sich auf den Wert von „this.state“ unter „Preact“ aus, beispielsweise „this.state“ in „componentWillUpdate“ später , setState zu diesem Zeitpunkt nicht. Es ist sowieso nutzlos.
setState Wenn Sie eine Funktion zum Ändern verwenden, sind die unter Preact übergebenen Requisiten prevProps, in React jedoch nextProps. Achten Sie beim SettingState in ComponentWillReceiveProps darauf.
Wenn das von Ihnen geschriebene Projekt sowohl mit React als auch Preact kompatibel sein muss:
Verwenden Sie setState nicht Unter „Reagieren“ wird der Status nicht unmittelbar vor der Ausführung derselben Komponentenaktualisierung aktualisiert. Achten Sie darauf, ob es einen Einfluss zwischen mehreren setStates gibt, und speichern Sie die alten Werte bei Bedarf manuell.
Verwenden Sie setState während des Komponentenaktualisierungslebenszyklus nicht, außer ComponentWillReceiveProps. Der nextState-Lebenszyklus wird bereitgestellt und nextState kann direkt geändert werden.
Vermeiden Sie die Verwendung der setState-Funktionsänderungsmethode. Wenn Sie sie in ComponentWillReceiveProps verwenden, verwenden Sie prevProps(this.props) und nextProps im Lebenszyklus.
p.s.: Die offizielle Version von antd-mobile 2.0 ist auch mit React und Preact kompatibel. Es handelt sich um eine leichte, schnelle und benutzerfreundliche Bibliothek für mobile Komponenten , wartet darauf, dass du es verwendest~ [Portal 】
Das obige ist der detaillierte Inhalt vonDer Unterschied zwischen setState in React und Preact. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!