reactjs / reactjs/react.dev

Highlight Possible Necessity of keys for Conditional Rendering

Ouverte
#1,779 0 commentaires 5 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
JavaScript
Étoiles
11.8k
Forks
7.9k
Merge moyen
1 j 11 h
PR mergées (30 j)
11

Description

Motivation

Keys may be necessary outside the context of any "list" or array, especially when using conditional rendering. This isn't emphasized enough in the docs, and examples (therein and elsewhere) tend to lead to a false association between keys as having directly to do with map(), <li> elements, or JavaScript arrays. As I understand it, at its root, keys have to do with children, and type correspondence based on position during reconciliation.

Related issues such as https://github.com/reactjs/reactjs.org/issues/79 don't seem to directly address this.

Personal Experience

Most recommendations I find online seem to boil down to "use keys when using map()"(or <li> or arrays). It's rare to find a discussion related to conditional rendering and most people tend to be unaware of it.

I've been in a project wherein conditional rendering was heavily used, which led to a hard to find bug due to the absence of keys.

Code snippet in render()

return (
            <div>
               { this.state.showCounter2 ? 
               (
                <React.Fragment>  
                    <CounterWithLifeCycleLog name={'myCounter1'} 
                    counter={0} />
                    <CounterWithLifeCycleLog name={'myCounter2'} 
                    counter={this.state.counter2} />
                    <CounterWithLifeCycleLog name={'myCounter3'} 
                    counter={0} />
                </React.Fragment>

               ) : (
                <React.Fragment>
                    <CounterWithLifeCycleLog name={'myCounter1'} 
                    counter={0} />  
                    <CounterWithLifeCycleLog name={'myCounter3'} 
                    counter={0} />    
                </React.Fragment>

               )

The above code has a bug. When this.state.showCounter2 moves from true to false myCounter3 will be unmounted instead of myCounter2. Then the new myCounter3 will reuse the backing instance of myCounter2, maintaining its internal state.

It is true that this could be avoided by using the following instead:

&& <CounterWithLifeCycleLog name={'myCounter2'} 
                    counter={this.state.counter2} />

The former example, however, is valid conditional rendering as well.

Proposed solution

An explicit mention of this confusion, an example involving conditional rendering (not using <li>, map(), or arrays), and perhaps a link to this blog post and perhaps the How to force remounting on React components related stackoverflow question.

Also, currently, all warnings related to keys seem to either have to do with arrays or iterators, perhaps a light warning when using conditional rendering could be helpful (though I can see how this will add way too much clutter), or some way to incorporate it into existing warnings.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par localiser les sections de la documentation React qui expliquent les keys, les listes et la reconciliation. Utilisez l’exemple fourni de rendu conditionnel pour présenter la distinction avec map(), les éléments de liste et les tableaux. Le travail est terminé lorsque la documentation explique clairement quand les keys sont importantes dans le rendu conditionnel et inclut un exemple dédié ; toute modification des avertissements est considérée comme facultative.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
javascript, react
Domaine
documentation
Type d'issue
Documentation
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
45/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.