J'ai un objet observable externe (au composant) sur lequel je veux écouter les changements. Lorsque l'objet est mis à jour, il émet des événements de modification, puis je souhaite restituer le composant lorsqu'une modification est détectée.
Avec un niveau supérieur, React.render
cela a été possible, mais au sein d'un composant, cela ne fonctionne pas (ce qui est logique puisque la render
méthode renvoie simplement un objet).
Voici un exemple de code:
export default class MyComponent extends React.Component {
handleButtonClick() {
this.render();
}
render() {
return (
<div>
{Math.random()}
<button onClick={this.handleButtonClick.bind(this)}>
Click me
</button>
</div>
)
}
}
Cliquer sur le bouton appelle en interne this.render()
, mais ce n'est pas ce qui provoque réellement le rendu (vous pouvez le voir en action car le texte créé par {Math.random()}
ne change pas). Cependant, si j'appelle simplement this.setState()
au lieu de this.render()
, cela fonctionne très bien.
Je suppose donc que ma question est la suivante: les composants React doivent-ils avoir un état pour pouvoir être rendus? Existe-t-il un moyen de forcer le composant à se mettre à jour à la demande sans changer l'état?
this.forceUpdate()
c'est la bonne solution alors que le reste de toutes les réponses et plusieurs commentaires sont contre l'utilisationforceUpdate()
. Serait-il alors bon de dire que la question n'a pas encore obtenu une solution / réponse appropriée?Réponses:
Dans votre composant, vous pouvez appeler
this.forceUpdate()
pour forcer un nouveau rendu.Documentation: https://facebook.github.io/react/docs/component-api.html
la source
this.forceUpdate()
ne soit pas une très bonne solution au problème des demandeurs, c'est la bonne réponse à la question posée dans le titre. Bien qu'il soit généralement à éviter, il existe des situations où forceUpdate est une bonne solution.shouldComponentUpdate()
rendre votre solution futile.forceUpdate
doit être évité car il s'écarte d'un état d'esprit React. Les documents React citent un exemple de cas d'forceUpdate
utilisation:Cependant, je voudrais proposer l'idée que même avec des objets profondément imbriqués, ce
forceUpdate
n'est pas nécessaire. En utilisant une source de données immuable, le suivi des modifications devient bon marché; un changement se traduira toujours par un nouvel objet, il nous suffit donc de vérifier si la référence à l'objet a changé. Vous pouvez utiliser la bibliothèque Immutable JS pour implémenter des objets de données immuables dans votre application.La modification de la clé de l'élément que vous souhaitez restituer fonctionnera. Définissez l'accessoire de clé sur votre élément via l'état, puis lorsque vous souhaitez mettre à jour l'état d'ensemble pour avoir une nouvelle clé.
Ensuite, un changement se produit et vous réinitialisez la clé
Je veux noter que cela remplacera l'élément sur lequel la clé change. Un exemple où cela pourrait être utile est lorsque vous avez un champ de saisie de fichier que vous souhaitez réinitialiser après un téléchargement d'image.
Bien que la vraie réponse à la question du PO soit,
forceUpdate()
j'ai trouvé cette solution utile dans différentes situations. Je tiens également à noter que si vous vous retrouvez à utiliser,forceUpdate
vous voudrez peut-être revoir votre code et voir s'il existe une autre façon de faire les choses.NOTE 1-9-2019:
Ce qui précède (changer la clé) remplacera complètement l'élément. Si vous vous trouvez à mettre à jour la clé pour apporter des modifications, vous avez probablement un problème ailleurs dans votre code. L'utilisation
Math.random()
de la clé recréera l'élément avec chaque rendu. Je ne recommanderais PAS de mettre à jour la clé comme ceci car react utilise la clé pour déterminer la meilleure façon de restituer les choses.la source
key
. Premièrement, son intention n'est pas claire. Un lecteur de votre code devra travailler dur pour comprendre pourquoi vous utilisezkey
cette méthode. Deuxièmement, ce n'est pas plus pur queforceUpdate
. "Pure" React signifie que la présentation visuelle de votre composant dépend à 100% de son état, donc si vous changez un état, il se met à jour. Si cependant, vous avez des objets profondément imbriqués (le scénario lesforceUpdate
documents citent une raison de l'utiliser), alors utiliser leforceUpdate
rend clair. Troisièmement,Math.random()
c'est… aléatoire. Théoriquement, il pourrait générer le même nombre aléatoire.forceUpdate
est la façon de réagir de React.En fait,
forceUpdate()
c'est la seule solution correcte, car ellesetState()
pourrait ne pas déclencher un nouveau rendu si une logique supplémentaire est implémentée dansshouldComponentUpdate()
ou lorsqu'elle revient simplementfalse
.Forcer la mise à jour()
setState ()
forceUpdate()
peut être appelé depuis votre composant parthis.forceUpdate()
Hooks: Comment puis-je forcer le rendu des composants avec des hooks dans React?
BTW: Êtes-vous en train de muter ou vos propriétés imbriquées ne se propagent-elles pas?
la source
this.state
extérieur du constructeur devrait également générer une erreur. Pourrait ne pas l'avoir fait en 2016; mais je suis quasiment sûr qu'il le fait maintenant.J'ai évité
forceUpdate
en suivantdonc en faisant une telle amélioration de code, votre composant sera UNIQUE et restituera naturellement
la source
this.state.rows.map((item) => <MyComponent item={item} key={item.id} /> )
Lorsque vous souhaitez que deux composants React communiquent, qui ne sont pas liés par une relation (parent-enfant), il est conseillé d'utiliser Flux ou des architectures similaires.
Ce que vous voulez faire, c'est écouter les modifications du magasin de
composants observable, qui contient le modèle et son interface, et enregistrer les données qui provoquent le changement du rendu commestate
dansMyComponent
. Lorsque le magasin envoie les nouvelles données, vous modifiez l'état de votre composant, ce qui déclenche automatiquement le rendu.Normalement, vous devriez essayer d'éviter d'utiliser
forceUpdate()
. De la documentation:la source
react-redux
pour mapper automatiquement l'état du magasin aux accessoires de composant chaque fois que nécessaire en fonction d'une fonction de mappage que vous fournissez.forceUpdate
utiliser des crochets ou HOC faire votre choix
À l'aide de crochets ou du modèle HOC (composant d'ordre supérieur) , vous pouvez avoir des mises à jour automatiques lorsque vos magasins changent. Il s'agit d'une approche très légère sans cadre.
useStore Hooks façon de gérer les mises à jour du magasin
withStores HOC gère les mises à jour du magasin
Classe SimpleStore
Comment utiliser
Dans le cas des crochets:
Dans le cas de HOC:
ASSUREZ-VOUS D'exporter vos magasins en tant que singleton pour bénéficier du changement global comme ceci:
Cette approche est assez simple et fonctionne pour moi. Je travaille également dans de grandes équipes et j'utilise Redux et MobX et je trouve que celles-ci sont également bonnes, mais juste beaucoup de passe-partout. Personnellement, j'aime ma propre approche parce que j'ai toujours détesté beaucoup de code pour quelque chose qui peut être simple quand vous en avez besoin.
la source
this._data = {...this._data, ...newData}
.Les autres réponses ont essayé d'illustrer comment vous pouviez, mais le fait est que vous ne devriez pas . Même la solution hacky de changer la clé manque le point. La puissance de React consiste à abandonner le contrôle de la gestion manuelle du moment où quelque chose doit être rendu, et au lieu de simplement se préoccuper de la façon dont quelque chose doit être mappé sur les entrées. Ensuite, fournissez un flux d'entrées.
Si vous devez forcer manuellement le re-rendu, vous ne faites certainement pas quelque chose de bien.
la source
Vous pouvez le faire de deux manières:
1. Utilisez la
forceUpdate()
méthode:Il y a quelques problèmes qui peuvent survenir lors de l'utilisation de la
forceUpdate()
méthode. Un exemple est qu'il ignore lashouldComponentUpdate()
méthode et restitue la vue indépendamment du fait qu'elleshouldComponentUpdate()
retourne false. Pour cette raison, l'utilisation de forceUpdate () doit être évitée autant que possible.2. Passer this.state à la
setState()
méthodeLa ligne de code suivante résout le problème de l'exemple précédent:
Vraiment, tout cela ne fait que remplacer l'état actuel par l'état actuel qui déclenche un nouveau rendu. Ce n'est toujours pas nécessairement la meilleure façon de faire les choses, mais cela résout certains des problèmes que vous pourriez rencontrer en utilisant la méthode forceUpdate ().
la source
this.setState(prevState => prevState);
Il existe plusieurs façons de rendre à nouveau votre composant:
La solution la plus simple consiste à utiliser la méthode forceUpdate ():
Une autre solution consiste à créer la clé non utilisée dans l'état (nonUsedKey) et à appeler la fonction setState avec la mise à jour de cette nonUsedKey:
Ou réécrivez tout l'état actuel:
Le changement des accessoires fournit également un rendu des composants.
la source
Pour être complet, vous pouvez également y parvenir dans les composants fonctionnels:
Ou, comme crochet réutilisable:
Voir: https://stackoverflow.com/a/53215514/2692307
Veuillez noter que l'utilisation d'un mécanisme de mise à jour forcée est toujours une mauvaise pratique car elle va à l'encontre de la mentalité de réaction, elle doit donc être évitée si possible.
la source
Nous pouvons utiliser this.forceUpdate () comme ci-dessous.
La partie Element 'Math.random' du DOM n'est mise à jour que si vous utilisez setState pour restituer le composant.
Toutes les réponses ici sont correctes et complètent la question de la compréhension .. comme nous savons que le rendu d'un composant sans utiliser setState ({}) est en utilisant la forceUpdate ().
Le code ci-dessus s'exécute avec setState comme ci-dessous.
la source
Juste une autre réponse pour sauvegarder la réponse acceptée :-)
React décourage l'utilisation de,
forceUpdate()
car ils ont généralement une approche très «c'est la seule façon de le faire» envers la programmation fonctionnelle. C'est bien dans de nombreux cas, mais de nombreux développeurs React ont un arrière-plan OO, et avec cette approche, il est tout à fait correct d'écouter un objet observable.Et si vous le faites, vous savez probablement que vous DEVEZ restituer lorsque les "déclenchements" observables, et comme tel, vous DEVRIEZ utiliser
forceUpdate()
et c'est en fait un plus quishouldComponentUpdate()
n'est PAS impliqué ici.Des outils comme MobX, qui adopte une approche OO, le font en fait sous la surface (en fait, MobX appelle
render()
directement)la source
J'ai préféré éviter forceUpdate (). Une façon de forcer le re-rendu est d'ajouter la dépendance de render () sur une variable externe temporaire et de changer la valeur de cette variable en fonction des besoins.
Voici un exemple de code:
Appelez this.forceChange () lorsque vous devez forcer un nouveau rendu.
la source
ES6 - J'inclus un exemple, qui m'a été utile:
Dans une "instruction if courte", vous pouvez passer une fonction vide comme celle-ci:
Cela semble être l'approche la plus courte.
la source
forceUpdate();
fonctionnera mais il est conseillé d'utilisersetState();
la source
Afin d'accomplir ce que vous décrivez, essayez this.forceUpdate ().
la source
Une autre façon appelle
setState
, et préserver l' état:this.setState(prevState=>({...prevState}));
la source
forceUpdate (), mais chaque fois que j'entends quelqu'un en parler, cela a été suivi, vous ne devriez jamais l'utiliser.
la source
Vous pouvez utiliser forceUpdate () pour plus de détails, vérifiez ( forceUpdate () ).
la source