reactjs / reactjs/react.dev

Highlight Possible Necessity of keys for Conditional Rendering

Abierto
#1,779 0 comentarios 5 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
JavaScript
Estrellas
11.8k
Forks
7.9k
Merge medio
1 d 11 h
PR fusionados (30 d)
11

Descripción

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.

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza localizando las secciones de la documentación de React que explican las keys, las listas y la reconciliación. Usa el ejemplo proporcionado de renderizado condicional para enmarcar la diferencia con map(), los elementos de lista y los arrays. El trabajo estará terminado cuando la documentación explique claramente cuándo importan las keys en el renderizado condicional e incluya un ejemplo específico; cualquier cambio en las advertencias se considera un alcance opcional.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
javascript, react
Área
documentation
Tipo de issue
Documentación
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
45/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.