


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('onChange', this.doSearch) } componentWillUnmount() { this.props.events.off('onChange', 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 = '' bar = '' 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('fooChange', this.fooChange) this.props.events.on('barChange', this.barChange) } componentWillUnmount() { this.props.events.off('fooChange', this.fooChange) this.props.events.off('barChange', 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 'FOO_CHANGE': case 'BAR_CHANGE': { 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 = '' get foo() { return this._foo } set foo(value) { this._foo = value this.search() } search() { // ... } }// 当然如果没有getter和setter的话也可以通过这种方式实现class Model { foo = '' 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 = '00' @observable minute = '00' @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 = '' @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 = '' @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 = '' @observable searchResult = [] disposers = [] fetch = () => { // ... } dispose() { this.disposers.forEach(disposer => disposer()) } constructor() { this.disposers.push( observe(this, 'loading', this.fetch), observe(this, 'keyword', 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 :
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!

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,

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.

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.

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

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

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

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

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


Outils d'IA chauds

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

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

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

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
Le dernier (2018.2.1) outil de développement intégré PHP professionnel

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

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
Puissant environnement de développement intégré PHP
