Heim  >  Artikel  >  Web-Frontend  >  Eine detaillierte Einführung in kontrollierte und unkontrollierte Komponenten in React

Eine detaillierte Einführung in kontrollierte und unkontrollierte Komponenten in React

亚连
亚连Original
2018-06-15 14:47:471378Durchsuche

In diesem Artikel werden hauptsächlich die kontrollierten und unkontrollierten Komponenten der ausführlichen React-Programmierung vorgestellt. Jetzt teile ich ihn mit Ihnen und gebe ihn als Referenz.

Es gibt nicht viele Informationen über kontrollierte Komponenten und unkontrollierte Komponenten auf der offiziellen Website und inländischen Websites. Manche Leute halten es für optional und kümmern sich nicht darum. Dies zeigt nur die Leistungsfähigkeit von React, die Anforderungen von Projekten unterschiedlicher Größe zu erfüllen. Wenn Sie beispielsweise nur eine einfache Datenanzeige wie ListView durchführen und die Daten erfassen, reichen eine for-Schleife und {} aus. Es gibt jedoch eine große Anzahl von Berichten im Hintergrundsystem, und ohne dass verschiedene Formulare miteinander verknüpft sind gesteuerte Komponenten, es wird wirklich nicht funktionieren.

Kontrollierte Komponenten und unkontrollierte Komponenten sind die Einstiegspunkte für React, um Formulare zu verarbeiten. Aus der Sicht von React muss der Autor die Daten alles kontrollieren lassen oder einfach verstehen, dass die Generierung und Aktualisierung der Seite die JSX-Anweisungen getreu ausführen muss.

Formularelemente haben jedoch ihre eigenen Besonderheiten. Benutzer können die Darstellung der Benutzeroberfläche durch Tastatureingabe und Mausauswahl ändern. Die Änderung der Schnittstelle bedeutet auch, dass einige Daten geändert wurden. Die offensichtlicheren sind der Wert der Eingabe, das innereHTML des Textbereichs und das Häkchen des Radios/Kontrollkästchens. Die weniger offensichtlichen sind der ausgewählte und der selectedIndex die Option, die passiv modifiziert werden.

 <input value="{this.state.value}"/>

Wenn der input.value vom state.value der Komponente übernommen wird, wenn der Benutzer eine Eingabeänderung vornimmt und JSX dann die Ansicht erneut zeichnet, übernimmt der input.value dann den neuen Wert des Benutzers oder den des Status? neuer Wert? Wert? Basierend auf dieser Meinungsverschiedenheit lieferte React eine Kompromisslösung, die von beiden unterstützt wurde, und das heutige Thema war geboren.

React glaubt, dass value/checked nicht alleine existieren kann und zusammen mit onInput/onChange/disabed/readOnly und anderen Eigenschaften oder Ereignissen verwendet werden muss, die value/checked steuern. Zusammen bilden sie eine kontrollierte Komponente, die von JSX gesteuert wird. Wenn der Benutzer diese zusätzlichen Eigenschaften und Ereignisse nicht schreibt, fügt das Framework intern einige Ereignisse hinzu, z. B. onClick, onInput und onChange, wodurch Sie daran gehindert werden, Eingaben oder Auswahlen vorzunehmen und den Wert zu ändern. Innerhalb des Frameworks gibt es eine hartnäckige Variable, die ich persistValue nenne, die den ihr zuletzt von JSX zugewiesenen Wert beibehält und nur durch interne Ereignisse geändert werden kann.

Wir können also behaupten, dass die kontrollierte Komponente die Wertkontrolle ist, die durch Ereignisse vervollständigt werden kann.

In kontrollierten Komponenten kann persistValue jederzeit aktualisiert werden.

Sehen wir uns noch einmal die unkontrollierten Komponenten an. Da value/checked bereits belegt ist, aktiviert React einen weiteren Satz ignorierter Attribute in HTML, defaultValue/defaultChecked. Es wird allgemein angenommen, dass sie value/checked ähneln, d. h. wenn kein Wert vorhanden ist, wird der Wert von defaultValue als Wert betrachtet.

Wir haben oben gesagt, dass die Anzeige von Formularelementen durch den internen persistValue gesteuert wird, sodass defaultXXX auch persistValue synchronisiert und persistValue dann das DOM synchronisiert. Der Ausgangspunkt unkontrollierter Komponenten besteht jedoch darin, den Benutzeroperationen treu zu bleiben. Wenn der Benutzer

input.value = "xxxx"

in den Code eingibt, wird

<input defaultvalue="{this.state.value}"/>

nicht mehr wirksam und ist immer xxxx.

Wie geht das und wie erkennt man, ob die Änderung von innerhalb oder außerhalb des Frameworks kommt? Ich habe den Quellcode von React durchgesehen und es stellte sich heraus, dass es etwas namens valueTracker gibt, um Benutzereingaben zu verfolgen

var tracker = {
  getValue: function () {
   return currentValue;
  },
  setValue: function (value) {
   currentValue = &#39;&#39; + value;
  },
  stopTracking: function () {
   detachTracker(node);
   delete node[valueField];
  }
 };
 return tracker;
}

Dieses Ding wird über Object.defineProperty in den Wert des Elements eingegeben/überprüft, damit es Bescheid weiß Der Benutzer weist ihm einen Wert zu.

Aber value/checked sind immer noch zwei Kernattribute, die zu viele interne Mechanismen beinhalten (wie value und oninput, onchange, Eingabemethodenereignisse oncompositionstart,

compositionchange, oncompositionend, onpaste, oncut), Um den Wert/die Prüfung reibungslos zu ändern, verwendet

auch Object.getOwnPropertyDescriptor. Wenn ich mit IE8 kompatibel sein möchte, gibt es kein so fortschrittliches Gadget. Ich wähle einen anderen, sichereren Ansatz und

ändere einfach defaultValue/defaultChecked mit Object.defineProperty.

Zuerst füge ich dem Element ein _uncontrolled-Attribut hinzu, um anzuzeigen, dass ich defaultXXX gekapert habe. Fügen Sie dann einen weiteren Schalter, _observing, zur Set-Methode hinzu, die das Objekt beschreibt (der dritte Parameter von Object.defineProperty). Wenn die Ansicht innerhalb des Frames aktualisiert wird, ist dieser Wert „false“. Nach der Aktualisierung wird er auf „true“ gesetzt.

Auf diese Weise wissen Sie, ob input.defaultValue = "xxx" vom Benutzer oder vom Framework geändert wurde.

if (!dom._uncontrolled) {
  dom._uncontrolled = true;
  inputMonitor.observe(dom, name); //重写defaultXXX的setter/getter
}
dom._observing = false;//此时是框架在修改视图,因此需要关闭开关
dom[name] = val;
dom._observing = true;//打开开关,来监听用户的修改行为

Die Implementierung von inputMonitor ist wie folgt

export var inputMonitor = {};
var rcheck = /checked|radio/;
var describe = {
  set: function(value) {
    var controllProp = rcheck.test(this.type) ? "checked" : "value";
    if (this.type === "textarea") {
      this.innerHTML = value;
    }
    if (!this._observing) {
      if (!this._setValue) {
        //defaultXXX只会同步一次_persistValue
        var parsedValue = (this[controllProp] = value);
        this._persistValue = Array.isArray(value) ? value : parsedValue;
        this._setValue = true;
      }
    } else {
      //如果用户私下改变defaultValue,那么_setValue会被抺掉
      this._setValue = value == null ? false : true;
    }
    this._defaultValue = value;
  },
  get: function() {
    return this._defaultValue;
  },
  configurable: true
};
 
inputMonitor.observe = function(dom, name) {
  try {
    if ("_persistValue" in dom) {
      dom._setValue = true;
    }
    Object.defineProperty(dom, name, describe);
  } catch (e) {}
};

Ich habe aus Versehen so einen hirnverbrennenden Code gepostet. Das ist eine schlechte Angewohnheit von Programmierern. An diesem Punkt versteht jedoch jeder, dass sowohl offizielle Reaktionen als auch Anu/Qreact Benutzereingaben über Object.defineProperty steuern.

Damit wir das Verhalten des folgenden Codes verstehen können

  var a = ReactDOM.render(<textarea defaultValue="foo" />, container);
  ReactDOM.render(<textarea defaultValue="bar" />, container);
  ReactDOM.render(<textarea defaultValue="noise" />, container);
  expect(a.defaultValue).toBe("noise");
  expect(a.value).toBe("foo");
  expect(a.textContent).toBe("noise");
  expect(a.innerHTML).toBe("noise");

Da der Benutzer den Standardwert nicht manuell geändert hat, war dom._setValue immer falsch/undefiniert, sodass _persistValue immer geändert werden kann.

Ein weiteres Beispiel:

var renderTextarea = function(component, container) {
  if (!container) {
    container = document.createElement("p");
  }
  const node = ReactDOM.render(component, container);
  node.defaultValue = node.innerHTML.replace(/^\n/, "");
  return node;
};
 
const container = document.createElement("p");
//注意这个方法,用户在renderTextarea中手动改变了defaultValue,_setValue就变成true
const node = renderTextarea(<textarea defaultValue="giraffe" />, container);
 
expect(node.value).toBe("giraffe");
 
// _setValue后,gorilla就不能同步到_persistValue,因此还是giraffe
renderTextarea(<textarea defaultValue="gorilla" />, container);
// expect(node.value).toEqual("giraffe");
 
node.value = "cat";
// 这个又是什么回事了呢,因此非监控属性是在diffProps中批量处理的,在监控属性,则是在更后的方法中处理
// 检测到node.value !== _persistValue,于是重写 _persistValue = node.value,于是输出cat
renderTextarea(<textarea defaultValue="monkey" />, container);
expect(node.value).toEqual("cat");

Einfache Textklasse: Text, Textbereich, JSX-Wert, immer in String konvertiert

type="number"-Steuerung, Wert Es ist immer eine Zahl . Wenn es nicht ausgefüllt ist oder „“ lautet, wird es in „0“ umgewandelt.

Radio hat einen Verknüpfungseffekt. Es kann nur eine Radiosteuerung mit demselben Namen unter demselben übergeordneten Knoten ausgewählt werden.

Der Wert/Standardwert von Select unterstützt Arrays und führt keine Konvertierung durch. Wenn der Benutzer jedoch das Optionselement unten hinzufügt oder löscht, ändert sich die Auswahl entsprechend.

Darüber hinaus kann die Auswahl in Fuzzy-Matching und Exact-Matching unterteilt werden.

//精确匹配
var dom = ReactDOM.render(
  <select value={222}>
    <option value={111}>aaa</option>
    <option value={"222"}>xxx</option>
    <option value={222}>bbb</option>
    <option value={333}>ccc</option>
  </select>,
  container
);
expect(dom.options[2].selected).toBe(true);//选中第三个
//模糊匹配
var dom = ReactDOM.render(
  <select value={222}>
    <option value={111}>aaa</option>
    <option value={"222"}>xxx</option>
    <option value={333}>ccc</option>
  </select>,
  container
);
expect(dom.options[2].selected).toBe(true);//选中第二个

凡此种种,React/anu都是做了大量工作,迷你如preact/react-lite之流则可能遇坑。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在vue.js中如何实现数据分发slot

在Vue中有关使用ajax方法有哪些?

通过vue如何引入公共css文件

Das obige ist der detaillierte Inhalt vonEine detaillierte Einführung in kontrollierte und unkontrollierte Komponenten in React. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn