Cela peut marcher sur cette ligne entre responsable et opiniâtre, mais je vais et vient sur la façon de structurer un composant ReactJS à mesure que la complexité augmente et pourrait utiliser une certaine direction.
Venant d'AngularJS, je souhaite transmettre mon modèle au composant en tant que propriété et demander au composant de modifier directement le modèle. Ou devrais-je diviser le modèle en différentes state
propriétés et le recompiler lors du renvoi en amont? Quelle est la manière ReactJS?
Prenons l'exemple d'un éditeur d'articles de blog. Essayer de modifier le modèle finit directement par ressembler à:
var PostEditor = React.createClass({
updateText: function(e) {
var text = e.target.value;
this.props.post.text = text;
this.forceUpdate();
},
render: function() {
return (
<input value={this.props.post.text} onChange={this.updateText}/>
<button onClick={this.props.post.save}/>Save</button>
);
}
});
Ce qui semble faux.
Est-ce plus la manière React de créer notre text
propriété de modèle state
et de la recompiler dans le modèle avant de l'enregistrer comme:
var PostEditor = React.createClass({
getInitialState: function() {
return {
text: ""
};
},
componentWillMount: function() {
this.setState({
text: this.props.post.text
});
},
updateText: function(e) {
this.setState({
text: e.target.value
});
},
savePost: function() {
this.props.post.text = this.state.text;
this.props.post.save();
},
render: function() {
return (
<input value={this.state.text} onChange={this.updateText}/>
<button onClick={this.savePost}/>Save</button>
);
}
});
Cela ne nécessite pas d'appel this.forceUpdate()
, mais au fur et à mesure que le modèle grandit (un article peut avoir un auteur, un sujet, des balises, des commentaires, des notes, etc.), le composant commence à devenir vraiment compliqué.
La première méthode avec ReactLink est-elle la voie à suivre?
text
champ, nous ayons unesetText
méthode qui effectue la validation et d'autres choses. Je peux voir la méthode (2) fonctionner si ellesetText
est pure et renvoie une toute nouvelle instance du modèle. Cependant, sisetText
nous mettions simplement à jour l'état interne, nous aurions encore besoin d'appelerforceUpdate
, non?forceUpdate
, mais à ce moment-là, vous «fuyez» de React. Il peut être préférable de transmettre unsetState()
rappel au modèle opaque pour éviter d'avoir à déclencher manuellement des rendus.Mise à jour 2016: React est changé, et l'explication "props vs state" est devenue très simple. Si un composant a besoin de modifier des données - mettez-le dans un état, sinon dans des accessoires. Parce que les accessoires sont désormais en lecture seule .
Quelle est la différence exacte entre les accessoires et l'état?
Vous pouvez trouver une bonne explication ici (version complète)
la source
setProps
est obsolète et ne doit pas être utilisé. Le remplacement consiste à rendre le composant et à laisser React gérer les différences.De React doc
Depuis TrySpace : lorsque les accessoires (ou l'état) sont mis à jour (via setProps / setState ou parent), le composant est également restitué.
la source
Une lecture de Thinking in React :
la source
Je ne sais pas si je réponds à votre question, mais j'ai trouvé que, en particulier dans une application de grande taille / en croissance, le modèle Conteneur / Composant fonctionne incroyablement bien.
Vous avez essentiellement deux composants React:
Exemple
NB Cet exemple est probablement trop simple pour illustrer les avantages de ce modèle, car il est assez détaillé pour un cas aussi simple.
Avantages
En séparant la logique d'affichage et la gestion des données / états, vous disposez d'un composant d'affichage réutilisable qui:
Vous disposez également d'un composant conteneur qui gère toutes les communications externes. Cela devrait vous permettre d'être plus flexible sur la manière dont vous accédez à vos données si vous apportez des modifications sérieuses ultérieurement *.
Ce modèle rend également l'écriture et la mise en œuvre de tests unitaires beaucoup plus simples.
Après avoir répété plusieurs fois une grande application React, j'ai constaté que ce modèle rend les choses relativement indolores, en particulier lorsque vous avez des composants plus volumineux avec des styles calculés ou des interactions DOM compliquées.
* Lisez le modèle de flux et jetez un œil à
Marty.js , qui a largement inspiré cette réponse (et j'utilise beaucoup ces derniers temps)Redux (et react-redux ), qui implémentent extrêmement bien ce modèle.la source
Je pense que vous utilisez un anti-pattern que Facebook a déjà expliqué sur ce lien
Voici ce que vous trouvez:
La première fois que le composant interne est rendu, il aura {foo: 'bar'} comme valeur prop. Si l'utilisateur clique sur l'ancre, l'état du composant parent sera mis à jour à {value: {foo: 'barbar'}}, déclenchant le processus de re-rendu du composant interne, qui recevra {foo: 'barbar'} comme la nouvelle valeur de l'accessoire.
Le problème est que puisque le parent et les composants internes partagent une référence au même objet, lorsque l'objet subit une mutation sur la ligne 2 de la fonction onClick, l'accessoire du composant interne change. Ainsi, lorsque le processus de re-rendu démarre et que shouldComponentUpdate est appelé, this.props.value.foo sera égal à nextProps.value.foo, car en fait, this.props.value fait référence au même objet que nextProps.value.
Par conséquent, puisque nous manquerons le changement sur l'accessoire et court-circuiterons le processus de re-rendu, l'interface utilisateur ne sera pas mise à jour de 'bar' à 'barbar'
la source
Innercomponents
code?