Maison interface Web js tutoriel Explication détaillée des composants contrôlés par React et des composants non contrôlés

Explication détaillée des composants contrôlés par React et des composants non contrôlés

Dec 18, 2017 pm 04:21 PM
react 组件

Cet article vous explique principalement en détail les composants contrôlés et les composants non contrôlés de React. Il n'y a pas beaucoup d'informations sur les composants contrôlés et les composants non contrôlés sur le site officiel et les sites Web nationaux. Certaines personnes pensent qu'ils sont disponibles ou non, et. ils s'en moquent. Cela montre simplement la puissance de React pour répondre aux besoins de projets de différentes tailles. Par exemple, si vous effectuez simplement un simple affichage de données comme ListView et capturez les données, alors une boucle for et {} suffisent. Cependant, il existe un grand nombre de rapports dans le système d'arrière-plan et différents formulaires sont liés entre eux. Sans composants contrôlés, cela ne fonctionnera vraiment pas.

Les composants contrôlés et les composants non contrôlés sont les points d'entrée de React pour traiter les formulaires. Du point de vue de React, l'auteur doit laisser les données contrôler tout, ou simplement comprendre que la génération et la mise à jour de la page doivent exécuter fidèlement les instructions JSX.

Mais les éléments du formulaire ont leurs propres fonctionnalités spéciales. Les utilisateurs peuvent modifier l'affichage de l'interface via la saisie au clavier et la sélection de la souris. Le changement dans l'interface signifie également que certaines données ont été modifiées, les plus évidentes sont la valeur de l'entrée, la innerHTML de la zone de texte, la radio/case à cocher cochée, pas si Les plus évidentes sont les options selected et selectedIndex, qui sont modifiées passivement.

<input value={this.state.value} />
Copier après la connexion

Lorsque le input.value est extrait du state.value du composant, lorsque l'utilisateur effectue une modification d'entrée, puis que JSX redessine à nouveau la vue, le input.value prend-il la nouvelle valeur de l'utilisateur ou l'État ? une nouvelle valeur ? Sur la base de ce désaccord, React a proposé une solution de compromis soutenue par les deux, et le sujet d'aujourd'hui est né.

React estime que value/checked ne peut pas exister seul et doit être utilisé avec onInput/onChange/disabed/readOnly et d'autres propriétés ou événements qui contrôlent value/checked. Ensemble, ils forment un composant contrôlé, qui est contrôlé par JSX. Si l'utilisateur n'écrit pas ces propriétés et événements supplémentaires, le framework y ajoutera certains événements en interne, tels que onClick, onInput et onChange, vous empêchant de saisir ou de sélectionner et vous empêchant de modifier sa valeur. À l'intérieur du framework, il existe une variable tenace, que j'appelle persistValue, qui conserve la dernière valeur qui lui a été attribuée par JSX et ne peut être modifiée que par des événements internes.

Nous pouvons donc affirmer que la composante contrôlée est le contrôle de la valeur qui peut être complété par l' événement .

Dans les composants contrôlés, persistValue peut toujours être actualisé.

Regardons à nouveau les composants non contrôlés. Puisque value/checked est déjà occupé, React active un autre ensemble d'attributs ignorés en HTML, defaultValue/defaultChecked. On pense généralement qu'ils sont similaires à value/checked, c'est-à-dire que lorsque la valeur n'existe pas, la valeur de defaultValue est considérée comme une valeur.

Nous avons dit plus haut que l'affichage des éléments du formulaire est contrôlé par la persistValue interne, donc defaultXXX synchronisera également persistValue, puis persistValue synchronisera le DOM. Cependant, le point de départ des composants non contrôlés est d'être fidèle aux opérations de l'utilisateur. Si l'utilisateur saisit

input.value = "xxxx"
Copier après la connexion

puis

<input defaultValue={this.state.value} />
Copier après la connexion

dans le code, cela ne prendra plus effet. et sera toujours xxxx.

Comment fait-il cela, et comment identifier si la modification vient de l'intérieur ou de l'extérieur du cadre ? J'ai parcouru le code source de React, et il s'avère qu'il contient quelque chose appelé valueTracker pour suivre les entrées de l'utilisateur

var tracker = {
    getValue: function () {
      return currentValue;
    },
    setValue: function (value) {
      currentValue = '' + value;
    },
    stopTracking: function () {
      detachTracker(node);
      delete node[valueField];
    }
  };
  return tracker;
}
Copier après la connexion

Cette chose est entrée dans la valeur/vérifiée de l'élément via Object.defineProperty, donc Connaître les opérations d'attribution de valeur de l'utilisateur sur celui-ci.

Mais value/checked sont toujours deux attributs essentiels, impliquant trop de mécanismes internes (tels que value et oninput, onchange, les événements de méthode de saisie oncompositionstart,
compositionchange, oncompositionend, onpaste, oncut), afin pour modifier la valeur/vérifier en douceur,
doit également être utilisé Object.getOwnPropertyDescriptor. Si je veux être compatible avec IE8, il n’existe pas de gadget aussi avancé. J'adopte une autre approche plus sûre,
modifiez simplement defaultValue/defaultChecked avec Object.defineProperty.

J'ajoute d'abord un attribut _uncontrolled à l'élément pour indiquer que j'ai détourné defaultXXX. Ajoutez ensuite un autre commutateur, Object.defineProperty的第三个参数, à la méthode set de l'objet de description (_observing). Lorsque la vue est mise à jour à l'intérieur du cadre, cette valeur est fausse. Après la mise à jour, elle est définie sur vrai.

De cette façon, vous saurez si input.defaultValue = "xxx" a été modifié par l'utilisateur ou par le framework.

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

L'implémentation d'inputMonitor est la suivante

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) {}
};
Copier après la connexion

J'ai accidentellement publié un code aussi brûlant le cerveau, ce qui est une mauvaise habitude des codeurs. Cependant, à ce stade, tout le monde comprend que les réactions officielles et anu/qreact contrôlent les entrées des utilisateurs via Object.defineProperty.

Nous pouvons donc comprendre le comportement du code suivant

    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");
Copier après la connexion

Puisque l'utilisateur n'a pas modifié manuellement la valeur par défaut, dom._setValue a toujours été faux/non défini , donc _persistValue Peut toujours être modifié.

Autre exemple :

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");
Copier après la connexion

Bien sûr, il existe de nombreux types d'éléments de formulaire, et chaque élément de formulaire a également son comportement par défaut.

纯文本类:text, textarea, JSX的值,总是往字符串转换
type="number"的控制,值总是为数字,不填或为“”则转换为“0”
radio有联动效果,同一父节点下的相同name的radio控制只能选择一个。
select的value/defaultValue支持数组,不做转换,但用户对底下的option元素做增删操作,selected会跟着变动。

此外select还有模糊匹配与精确匹配之分。

//精确匹配
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);//选中第三个
Copier après la connexion
//模糊匹配
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);//选中第二个
Copier après la connexion

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

相关推荐:

react如何实现菜单权限控制?

React 内部机制探秘

React中组件的写法有哪些


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Vous avez un jeu croisé?
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment créer une application de chat en temps réel avec React et WebSocket Comment créer une application de chat en temps réel avec React et WebSocket Sep 26, 2023 pm 07:46 PM

Comment créer une application de chat en temps réel à l'aide de React et WebSocket Introduction : Avec le développement rapide d'Internet, la communication en temps réel a attiré de plus en plus d'attention. Les applications de chat en direct font désormais partie intégrante de la vie sociale et professionnelle moderne. Cet article expliquera comment créer une application simple de chat en temps réel à l'aide de React et WebSocket, et fournira des exemples de code spécifiques. 1. Préparation technique Avant de commencer à créer une application de chat en temps réel, nous devons préparer les technologies et outils suivants : React : un pour la construction

Guide pour la séparation du front-end et du back-end de React : Comment réaliser le découplage et le déploiement indépendant du front-end et du back-end Guide pour la séparation du front-end et du back-end de React : Comment réaliser le découplage et le déploiement indépendant du front-end et du back-end Sep 28, 2023 am 10:48 AM

Guide de séparation front-end et back-end de React : Comment réaliser un découplage front-end et back-end et un déploiement indépendant, des exemples de code spécifiques sont nécessaires Dans l'environnement de développement Web actuel, la séparation front-end et back-end est devenue une tendance. En séparant le code front-end et back-end, le travail de développement peut être rendu plus flexible, plus efficace et faciliter la collaboration en équipe. Cet article expliquera comment utiliser React pour réaliser une séparation front-end et back-end, atteignant ainsi les objectifs de découplage et de déploiement indépendant. Tout d’abord, nous devons comprendre ce qu’est la séparation front-end et back-end. Dans le modèle de développement Web traditionnel, le front-end et le back-end sont couplés

Comment créer des applications Web simples et faciles à utiliser avec React et Flask Comment créer des applications Web simples et faciles à utiliser avec React et Flask Sep 27, 2023 am 11:09 AM

Comment utiliser React et Flask pour créer des applications Web simples et faciles à utiliser Introduction : Avec le développement d'Internet, les besoins des applications Web deviennent de plus en plus diversifiés et complexes. Afin de répondre aux exigences des utilisateurs en matière de facilité d'utilisation et de performances, il devient de plus en plus important d'utiliser des piles technologiques modernes pour créer des applications réseau. React et Flask sont deux frameworks très populaires pour le développement front-end et back-end, et ils fonctionnent bien ensemble pour créer des applications Web simples et faciles à utiliser. Cet article détaillera comment exploiter React et Flask

Comment installer le composant DirectPlay de l'ancienne version de Windows 10 Comment installer le composant DirectPlay de l'ancienne version de Windows 10 Dec 28, 2023 pm 03:43 PM

De nombreux utilisateurs rencontrent toujours des problèmes lorsqu'ils jouent à certains jeux sur Win10, tels que le gel de l'écran et les écrans flous. À l'heure actuelle, nous pouvons résoudre le problème en activant la fonction de lecture directe, et la méthode de fonctionnement de la fonction est également très simple. Comment installer Directplay, l'ancien composant de Win10 1. Entrez "Panneau de configuration" dans la zone de recherche et ouvrez-le 2. Sélectionnez de grandes icônes comme méthode d'affichage 3. Recherchez "Programmes et fonctionnalités" 4. Cliquez sur la gauche pour activer ou désactiver les fonctions Win 5. Sélectionnez l'ancienne version ici Cochez simplement la case

Comment créer une application de messagerie fiable avec React et RabbitMQ Comment créer une application de messagerie fiable avec React et RabbitMQ Sep 28, 2023 pm 08:24 PM

Comment créer une application de messagerie fiable avec React et RabbitMQ Introduction : Les applications modernes doivent prendre en charge une messagerie fiable pour obtenir des fonctionnalités telles que les mises à jour en temps réel et la synchronisation des données. React est une bibliothèque JavaScript populaire pour créer des interfaces utilisateur, tandis que RabbitMQ est un middleware de messagerie fiable. Cet article explique comment combiner React et RabbitMQ pour créer une application de messagerie fiable et fournit des exemples de code spécifiques. Présentation de RabbitMQ :

Guide de l'utilisateur de React Router : Comment implémenter le contrôle de routage frontal Guide de l'utilisateur de React Router : Comment implémenter le contrôle de routage frontal Sep 29, 2023 pm 05:45 PM

Guide de l'utilisateur de ReactRouter : Comment implémenter le contrôle du routage frontal Avec la popularité des applications monopage, le routage frontal est devenu un élément important qui ne peut être ignoré. En tant que bibliothèque de routage la plus populaire de l'écosystème React, ReactRouter fournit des fonctions riches et des API faciles à utiliser, rendant la mise en œuvre du routage frontal très simple et flexible. Cet article expliquera comment utiliser ReactRouter et fournira quelques exemples de code spécifiques. Pour installer ReactRouter en premier, nous avons besoin

Comment créer des applications de traitement de données en temps réel à l'aide de React et Apache Kafka Comment créer des applications de traitement de données en temps réel à l'aide de React et Apache Kafka Sep 27, 2023 pm 02:25 PM

Comment utiliser React et Apache Kafka pour créer des applications de traitement de données en temps réel Introduction : Avec l'essor du Big Data et du traitement de données en temps réel, la création d'applications de traitement de données en temps réel est devenue la priorité de nombreux développeurs. La combinaison de React, un framework front-end populaire, et d'Apache Kafka, un système de messagerie distribué hautes performances, peut nous aider à créer des applications de traitement de données en temps réel. Cet article expliquera comment utiliser React et Apache Kafka pour créer des applications de traitement de données en temps réel, et

Composants angulaires et leurs propriétés d'affichage : comprendre les valeurs par défaut non bloquantes Composants angulaires et leurs propriétés d'affichage : comprendre les valeurs par défaut non bloquantes Mar 15, 2024 pm 04:51 PM

Le comportement d'affichage par défaut des composants du framework Angular ne concerne pas les éléments au niveau du bloc. Ce choix de conception favorise l'encapsulation des styles de composants et encourage les développeurs à définir consciemment la manière dont chaque composant est affiché. En définissant explicitement l'affichage des propriétés CSS, l'affichage des composants angulaires peut être entièrement contrôlé pour obtenir la mise en page et la réactivité souhaitées.

See all articles