ReactJS état vs prop
Cela peut être écrasant que la ligne entre la responsable et opiniâtre, mais je vais d'avant en arrière à la façon de structurer un ReactJS composante de la complexité se développe et pourrait utiliser une certaine direction.
Venant de AngularJS, je veux passer mon modèle dans le composant en tant que bien et ont le composant à modifier le modèle directement. Ou devrais-je être le fractionnement du modèle en différentes state
propriétés et la compilation de retour ensemble lors de l'envoi de retour en amont? Qu'est-ce que le ReactJS façon?
Prenons l'exemple d'un blog de l'éditeur. En essayant de modifier le modèle directement finit 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>
);
}
});
Qui semble erroné.
Est-il le plus Réagir de la façon de faire de notre text
modèle de propriété state
, et de les compiler en arrière 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 un appel à this.forceUpdate()
, mais comme le modèle se développe, (un poste peut avoir un auteur, sujet, tags, commentaires, notes, etc...) le composant commence à devenir vraiment compliqué.
Est la première méthode avec ReactLink le chemin à parcourir?
Vous devez vous connecter pour publier un commentaire.
Votre deuxième approche est plus comme ça. Réagir ne se soucie pas des modèles tellement qu'il se soucie de valeurs et comment ils coulent à travers votre application. Idéalement, votre modèle post devraient être stockées dans un seul composant à la racine. Ensuite, vous créez des composants enfants que chaque consommer des parties du modèle.
Vous pouvez passer des rappels aux enfants qui ont besoin de modifier vos données, et de les appeler à partir de l'enfant du composant.
De modifier cette.d'accessoires ou de cette.l'état directement n'est pas une bonne idée, parce que Réagir ne sera pas en mesure de revenir sur les modifications. C'est parce que de Réagir n'est un peu de la comparaison de votre post prop afin de déterminer si elle a changé.
J'ai fait ce jsfiddle pour montrer la façon dont les données pourraient découler de l'extérieur vers l'intérieur de la composante:
http://jsfiddle.net/jxg/M3CLB/
La
handleClick
méthode montre 3 façons de (im)correctement mise à jour de l'état:text
domaine, nous avons unsetText
méthode qui ne la validation et quelques autres trucs. Je peux voir la méthode (2) sisetText
est pur et renvoie une image de marque nouvelle instance du modèle. Toutefois, sisetText
juste les mises à jour de l'état interne que nous serions toujours besoin d'appelerforceUpdate
, droit?forceUpdate
, mais à ce stade, vous êtes une "fuite" de Réagir. Il pourrait être préférable de passer unsetState()
de rappel pour le modèle opaque pour éviter d'avoir à déclencher manuellement re-rend.La mise à jour de 2016:
Réagir est modifié, et à l'explication "props vs état" est devenu très simple. Si un composant a besoin de modifier des données - mettre dans un état, sinon dans les accessoires. Parce que accessoires sont en lecture seule maintenant.
Quelle est la différence exacte entre les accessoires et l'état?
Vous pouvez trouver une bonne explication ici (version complète)
setProps
est obsolète et ne doit pas être utilisé. Le remplacement est alors rendre à nouveau le composant et laisser agir de gérer les différences.De Réagir doc
De TrySpace: lorsque des accessoires (ou l'état) sont mises à jour (via setProps/setState ou parent) le composant re-rend ainsi.
Une lecture de La pensée de Réagir:
Je ne sais pas si je vais répondre à votre question, mais j'ai trouvé que, surtout dans une grande/application grandissante, le Conteneur ou la répétition de Composant fonctionne incroyablement bien.
Essentiellement, vous avez deux Réagissent composants:
Exemple
N. B. Cet exemple est sans doute trop simple pour illustrer les avantages de ce modèle, car il est assez détaillé pour une simple affaire.
Avantages
En gardant une logique d'affichage et de données/gestion de l'état séparé, vous avez une ré-utilisable composantes de l'écran qui:
Vous avez également un composant conteneur qui traite l'ensemble de la communication externe. Cela devrait rendre plus facile d'être flexible sur la façon dont vous accédez à vos données si vous faites de gros changements plus tard*.
Ce modèle fait également l'écriture et la mise en œuvre de tests unitaires beaucoup plus simple.
Avoir répété un grand Réagir application à quelques reprises, j'ai trouvé que ce modèle conserve des choses relativement indolore, surtout quand vous avez de grands composants calculé les styles ou les complexes interactions DOM.
*Lire sur le modèle de flux, et de prendre un coup d'oeil à
Marty.js, qui a largement inspiré cette réponse (et j'utilise beaucoup ces derniers temps)Redux (et réagir-redux), qui mettent en œuvre ce modèle extrêmement bien.Je pense que vous êtes à l'aide d'un anti-modèle qui Facebook a déjà expliqué à ce lien
Voici chose que vous êtes de trouver:
La première fois l'intérieur de la composante est rendu, il aura { foo: 'bar' } comme la valeur de la prop. Si l'utilisateur clique sur l'ancre, le composant parent de l'etat seront mis à jour à { valeur: { foo: 'barbar' } }, le déclenchement de la re-processus de rendu de l'intérieur de la composante, qui recevra { foo: 'barbar' } comme la nouvelle valeur de la prop.
Le problème est que, depuis que la mère et des composantes internes à part une référence à un même objet, lorsque l'objet sera muté à la ligne 2 de la fonction onClick, l'hélice à l'intérieur de la composante a va changer. Donc, quand le re-rendu processus commence, et shouldComponentUpdate est appelé, cette.accessoires de jeu.de la valeur.foo sera égal à nextProps.de la valeur.toto, parce qu'en fait, ce.accessoires de jeu.la valeur fait référence au même objet que nextProps.valeur.
Par conséquent, puisque nous allons manquer le changement sur l'hélice et le court-circuit de la re-processus de rendu, l'INTERFACE utilisateur de ne pas obtenir de mise à jour à partir de 'bar' pour 'barbar'
Innercomponents
code?