recherche
Maisoninterface Webtutoriel HTMLIntroduction détaillée aux solutions de programmation réactive front-end et à leurs lacunes (avec code)

Ce que cet article vous apporte est une introduction détaillée à la programmation réactive frontale et à ses lacunes (avec le code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. aide.

Beaucoup de choses dans le monde réel fonctionnent de manière réactive. Par exemple, nous recevrons des questions des autres, puis répondrons et donnerons les réponses correspondantes. Au cours du processus de développement, j'ai également appliqué beaucoup de design réactif et accumulé une certaine expérience, dans l'espoir d'inspirer les autres.

La principale différence entre la programmation réactive (Programmation réactive) et les idées de programmation ordinaires est que la programmation réactive fonctionne de manière push, tandis que la programmation non réactive fonctionne de manière pull. Par exemple, les événements sont une programmation réactive très courante. Nous faisons habituellement cela :

button.on('click', () => {  
    // ...})

De manière non réactive, cela deviendra comme ceci :

while (true) {  
    if (button.clicked) {        // ...
    }
}

Évidemment, que ce soit. en termes d'élégance du code ou d'efficacité d'exécution, les méthodes non réactives sont inférieures aux conceptions réactives.

Event Emitter

Event Emitter est une implémentation d'événement que la plupart des gens connaissent. Elle est très simple et pratique. Nous pouvons utiliser Event Emitter pour implémenter une conception de réactivité simple. , comme la recherche asynchrone suivante :

class Input extends Component {  
    state = {        value: ''
    }
    onChange = e => {        this.props.events.emit('onChange', e.target.value)
    }
    afterChange = value => {        this.setState({
            value
        })
    }
    componentDidMount() {        this.props.events.on('onChange', this.afterChange)
    }
    componentWillUnmount() {        this.props.events.off('onChange', this.afterChange)
    }
    render() {        
    const { value } = this.state        
    return (            <input value={value} onChange={this.onChange} />
        )
    }
}
class Search extends Component {  
    doSearch = (value) => {
        ajax(/* ... */).then(list => this.setState({
            list
        }))
    }
    componentDidMount() {
        this.props.events.on(&#39;onChange&#39;, this.doSearch)
    }
    componentWillUnmount() {
        this.props.events.off(&#39;onChange&#39;, this.doSearch)
    }
    render() {
        const { list } = this.state
        return (            <ul>
                {list.map(item => <li key={item.id}>{item.value}</li>)}            </ul>
        )
    }
}

Ici, nous constaterons que l'implémentation d'Event Emitter présente de nombreuses lacunes et que nous devons libérer manuellement les ressources dans composantWillUnmount. Sa capacité d'expression est insuffisante, par exemple, lorsque nous devons agréger plusieurs sources de données lors d'une recherche :

class Search extends Component {  
    foo = &#39;&#39;
    bar = &#39;&#39;
    doSearch = () => {
        ajax({
            foo,
            bar
        }).then(list => this.setState({
            list
        }))
    }
    fooChange = value => {        this.foo = value        this.doSearch()
    }
    barChange = value => {        this.bar = value        this.doSearch()
    }
    componentDidMount() {        this.props.events.on(&#39;fooChange&#39;, this.fooChange)        this.props.events.on(&#39;barChange&#39;, this.barChange)
    }
    componentWillUnmount() {        this.props.events.off(&#39;fooChange&#39;, this.fooChange)        this.props.events.off(&#39;barChange&#39;, this.barChange)
    }
    render() {        // ...
    }
}

Évidemment, l'efficacité du développement est très faible.

Redux

Redux utilise un flux d'événements pour implémenter la réactivité dans Redux, puisque le réducteur doit être une fonction pure, la seule façon d'implémenter la réactivité est l'abonnement. ou en middleware.

Si vous vous abonnez au magasin, puisque Redux ne peut pas savoir avec précision quelles données ont changé, il ne peut utiliser que la vérification sale. Par exemple :

function createWatcher(mapState, callback) {  
    let previousValue = null
    return (store) => {
        store.subscribe(() => {            const value = mapState(store.getState())            if (value !== previousValue) {
                callback(value)
            }
            previousValue = value
        })
    }
}const watcher = createWatcher(state => {  
    // ...}, () => {    // ...})

watcher(store)

Cette méthode présente deux inconvénients. Le premier est qu'il y aura des problèmes d'efficacité lorsque les données sont complexes et que la quantité de données est élevée. relativement grande ; Deuxièmement, si la fonction mapState dépend du contexte, elle sera difficile à gérer. Dans React-redux, le deuxième paramètre de mapStateToProps dans la fonction connect est les accessoires qui peuvent être transmis via le composant supérieur pour obtenir le contexte requis, mais de cette façon, l'écouteur devient un composant React et sera monté en tant que composant. monté. Et le déchargement est créé et détruit. Si on veut que cette réactivité soit indépendante des composants, il y aura un problème.

Une autre façon consiste à surveiller les modifications des données dans le middleware. Grâce à la conception de Redux, nous pouvons obtenir les modifications de données correspondantes en écoutant des événements spécifiques (Action).

const search = () => (dispatch, getState) => {  
    // ...}const middleware = ({ dispatch }) => next => action => {  
    switch action.type {        case &#39;FOO_CHANGE&#39;:        case &#39;BAR_CHANGE&#39;: {            const nextState = next(action)            // 在本次dispatch完成以后再去进行新的dispatch
            setTimeout(() => dispatch(search()), 0)            return nextState
        }        default:            return next(action)
    }
}

Cette méthode peut résoudre la plupart des problèmes, mais dans Redux, le middleware et le réducteur s'abonnent implicitement à tous les événements (Action), ce qui est évidemment déraisonnable, bien que dans Redux c'est tout à fait acceptable à condition qu'il n'y ait pas de performances problèmes.

Réactivité orientée objet

ECMASCRIPT 5.1 introduit les getters et les setters, et nous pouvons implémenter une réactivité via les getters et les setters.

class Model {  
    _foo = &#39;&#39;
    get foo() {        return this._foo
    }
    set foo(value) {        this._foo = value        this.search()
    }
    search() {        // ...
    }
}// 当然如果没有getter和setter的话也可以通过这种方式实现class Model {  
    foo = &#39;&#39;
    getFoo() {        return this.foo
    }
    setFoo(value) {        this.foo = value        this.search()
    }
    search() {        // ...
    }
}

Mobx et Vue utilisent cette méthode pour implémenter la réactivité. Bien entendu, nous pouvons également utiliser Proxy si la compatibilité n’est pas prise en compte.

Lorsque nous devons répondre à plusieurs valeurs puis obtenir une nouvelle valeur, nous pouvons le faire dans Mobx :

class Model {  
    @observable hour = &#39;00&#39;
    @observable minute = &#39;00&#39;
    @computed get time() {        return `${this.hour}:${this.minute}`
    }
}

Mobx collectera les valeurs dont dépend le temps à runtime, et recalculer la valeur temporelle lorsque ces valeurs changent (déclenchant le setter) est évidemment beaucoup plus pratique et efficace que la méthode EventEmitter, et est plus intuitif que le middleware Redux.

Mais il y a aussi un inconvénient ici. L'attribut calculé basé sur le getter ne peut décrire que la situation de y = f(x). Cependant, dans de nombreux cas, en réalité, f est une fonction asynchrone, donc ce sera le cas. devenu y = wait f( x), getter ne peut pas décrire cette situation.

Pour cette situation, nous pouvons utiliser l'exécution automatique fournie par Mobx :

class Model {  
    @observable keyword = &#39;&#39;
    @observable searchResult = []    constructor() {
        autorun(() => {            // ajax ...
        })
    }
}

Le processus de collecte des dépendances d'exécution étant complètement implicite, nous rencontrons souvent ici un problème qui consiste à collecter des dépendances inattendues :

class Model {  
    @observable loading = false
    @observable keyword = &#39;&#39;
    @observable searchResult = []    constructor() {
        autorun(() => {            if (this.loading) {                return
            }            // ajax ...
        })
    }
}

Évidemment, le chargement ici ne doit pas être collecté par l'exécution automatique recherchée. Afin de résoudre ce problème, du code supplémentaire sera ajouté, et le code supplémentaire peut facilement conduire à des erreurs. Alternativement, nous pouvons également spécifier manuellement les champs obligatoires, mais cette méthode nécessite quelques opérations supplémentaires :

class Model {  
    @observable loading = false
    @observable keyword = &#39;&#39;
    @observable searchResult = []
    disposers = []
    fetch = () => {        // ...
    }
    dispose() {        this.disposers.forEach(disposer => disposer())
    }    constructor() {        this.disposers.push(
            observe(this, &#39;loading&#39;, this.fetch),
            observe(this, &#39;keyword&#39;, this.fetch)
        )
    }
}class FooComponent extends Component {  
    this.mode = new Model()
    componentWillUnmount() {        this.state.model.dispose()
    }    // ...}

Et lorsque nous avons besoin de décrire la chronologie, Mobx est quelque peu incapable de le faire, par exemple vous. il faut retarder la recherche de 5 secondes.

Recommandations associées :

Version du framework front-end réactif pour puzzle du backend réactif officiellement publiée_html/css_WEB-ITnose

Utilisation un framework de développement front-end réactif très simple_html/css_WEB-ITnose


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
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
Difficulté à mettre à jour la mise en cache des pages Web officielles du compte: comment éviter l'ancien cache affectant l'expérience utilisateur après la mise à jour de la version?Difficulté à mettre à jour la mise en cache des pages Web officielles du compte: comment éviter l'ancien cache affectant l'expérience utilisateur après la mise à jour de la version?Mar 04, 2025 pm 12:32 PM

Le cache de mise à jour de la page Web du compte officiel, cette chose est simple et simple, et elle est suffisamment compliquée pour en boire un pot. Vous avez travaillé dur pour mettre à jour l'article officiel du compte, mais l'utilisateur a toujours ouvert l'ancienne version. Dans cet article, jetons un coup d'œil aux rebondissements derrière cela et comment résoudre ce problème gracieusement. Après l'avoir lu, vous pouvez facilement faire face à divers problèmes de mise en cache, permettant à vos utilisateurs de toujours ressentir le contenu le plus frais. Parlons d'abord des bases. Pour le dire franchement, afin d'améliorer la vitesse d'accès, le navigateur ou le serveur stocke des ressources statiques (telles que des images, CSS, JS) ou du contenu de la page. La prochaine fois que vous y accédez, vous pouvez le récupérer directement à partir du cache sans avoir à le télécharger à nouveau, et il est naturellement rapide. Mais cette chose est aussi une épée à double tranchant. La nouvelle version est en ligne,

Comment utiliser les attributs de validation du formulaire HTML5 pour valider l'entrée utilisateur?Comment utiliser les attributs de validation du formulaire HTML5 pour valider l'entrée utilisateur?Mar 17, 2025 pm 12:27 PM

L'article discute de l'utilisation des attributs de validation de formulaire HTML5 comme les limites requises, motifs, min, max et longueurs pour valider la saisie de l'utilisateur directement dans le navigateur.

Quelles sont les meilleures pratiques pour la compatibilité entre les navigateurs dans HTML5?Quelles sont les meilleures pratiques pour la compatibilité entre les navigateurs dans HTML5?Mar 17, 2025 pm 12:20 PM

L'article examine les meilleures pratiques pour assurer la compatibilité des navigateurs de HTML5, en se concentrant sur la détection des fonctionnalités, l'amélioration progressive et les méthodes de test.

Comment ajouter efficacement les effets de course aux images PNG sur les pages Web?Comment ajouter efficacement les effets de course aux images PNG sur les pages Web?Mar 04, 2025 pm 02:39 PM

Cet article démontre un ajout de bordure PNG efficace aux pages Web à l'aide de CSS. Il soutient que CSS offre des performances supérieures par rapport à JavaScript ou à des bibliothèques, détaillant comment ajuster la largeur, le style et la couleur des bordures pour un effet subtil ou proéminent

Quel est le but du & lt; datalist & gt; élément?Quel est le but du & lt; datalist & gt; élément?Mar 21, 2025 pm 12:33 PM

L'article traite du HTML & lt; Datalist & GT; élément, qui améliore les formulaires en fournissant des suggestions de saisie semi-automatique, en améliorant l'expérience utilisateur et en réduisant les erreurs. COMMANDE COMPRES: 159

Quel est le but du & lt; Progress & gt; élément?Quel est le but du & lt; Progress & gt; élément?Mar 21, 2025 pm 12:34 PM

L'article traite du HTML & lt; Progress & GT; élément, son but, son style et ses différences par rapport au & lt; mètre & gt; élément. L'objectif principal est de l'utiliser & lt; Progress & gt; pour l'achèvement des tâches et & lt; mètre & gt; pour stati

Comment utiliser le html5 & lt; time & gt; élément pour représenter les dates et les temps sémantiquement?Comment utiliser le html5 & lt; time & gt; élément pour représenter les dates et les temps sémantiquement?Mar 12, 2025 pm 04:05 PM

Cet article explique le html5 & lt; time & gt; élément de représentation sémantique de date / heure. Il souligne l'importance de l'attribut DateTime pour la lisibilité à la machine (format ISO 8601) à côté du texte lisible par l'homme, stimulant AccessIbilit

Quel est le but du & lt; mètre & gt; élément?Quel est le but du & lt; mètre & gt; élément?Mar 21, 2025 pm 12:35 PM

L'article traite du HTML & lt; mètre & gt; élément, utilisé pour afficher des valeurs scalaires ou fractionnaires dans une plage, et ses applications courantes dans le développement Web. Il différencie & lt; mètre & gt; De & lt; Progress & gt; et ex

See all articles

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)
2 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
4 Il y a quelques semainesBy尊渡假赌尊渡假赌尊渡假赌

Outils chauds

DVWA

DVWA

Damn Vulnerable Web App (DVWA) est une application Web PHP/MySQL très vulnérable. Ses principaux objectifs sont d'aider les professionnels de la sécurité à tester leurs compétences et leurs outils dans un environnement juridique, d'aider les développeurs Web à mieux comprendre le processus de sécurisation des applications Web et d'aider les enseignants/étudiants à enseigner/apprendre dans un environnement de classe. Application Web sécurité. L'objectif de DVWA est de mettre en pratique certaines des vulnérabilités Web les plus courantes via une interface simple et directe, avec différents degrés de difficulté. Veuillez noter que ce logiciel

PhpStorm version Mac

PhpStorm version Mac

Le dernier (2018.2.1) outil de développement intégré PHP professionnel

SublimeText3 version Mac

SublimeText3 version Mac

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

MinGW - GNU minimaliste pour Windows

MinGW - GNU minimaliste pour Windows

Ce projet est en cours de migration vers osdn.net/projects/mingw, vous pouvez continuer à nous suivre là-bas. MinGW : un port Windows natif de GNU Compiler Collection (GCC), des bibliothèques d'importation et des fichiers d'en-tête librement distribuables pour la création d'applications Windows natives ; inclut des extensions du runtime MSVC pour prendre en charge la fonctionnalité C99. Tous les logiciels MinGW peuvent fonctionner sur les plates-formes Windows 64 bits.

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Puissant environnement de développement intégré PHP