Digamos que tengo un componente de vista que tiene un render condicional:
render(){
if (this.state.employed) {
return (
<div>
<MyInput ref="job-title" name="job-title" />
</div>
);
} else {
return (
<div>
<MyInput ref="unemployment-reason" name="unemployment-reason" />
<MyInput ref="unemployment-duration" name="unemployment-duration" />
</div>
);
}
}
MyInput se parece a esto:
class MyInput extends React.Component {
...
render(){
return (
<div>
<input name={this.props.name}
ref="input"
type="text"
value={this.props.value || null}
onBlur={this.handleBlur.bind(this)}
onChange={this.handleTyping.bind(this)} />
</div>
);
}
}
Digamos que employedes verdad. Siempre que lo cambio a falso y la otra vista se procesa, solo unemployment-durationse reinicializa. También unemployment-reasonse rellena previamente con el valor de job-title(si se dio un valor antes de que cambiara la condición).
Si cambio el marcado en la segunda rutina de renderizado a algo como esto:
render(){
if (this.state.employed) {
return (
<div>
<MyInput ref="job-title" name="job-title" />
</div>
);
} else {
return (
<div>
<span>Diff me!</span>
<MyInput ref="unemployment-reason" name="unemployment-reason" />
<MyInput ref="unemployment-duration" name="unemployment-duration" />
</div>
);
}
}
Parece que todo funciona bien. Parece que React simplemente no logra diferenciar 'título del trabajo' y 'motivo de desempleo'.
Por favor dime qué estoy haciendo mal ...
javascript
reactjs
o01
fuente
fuente

data-reactiden cada uno de los elementosMyInput(oinput, como se ve en DOM) antes y después delemployedcambio?<div>. Losdata-reactidatributos parecen ser diferentes tanto en el div de envoltura como en el campo de entrada.job-titlela entrada obtiene iddata-reactid=".0.1.1.0.1.0.1", mientras que launemployment-reasonentrada obtiene iddata-reactid=".0.1.1.0.1.2.1"unemployment-duration?reactidatributos son idénticos enjob-titleyunemployment-reason, mientras que en el segundo ejemplo (con el intervalo diff) son diferentes.unemployment-durationelreactidatributo es siempre único.Respuestas:
Lo que probablemente está sucediendo es que React piensa que solo se agrega un
MyInput(unemployment-duration) entre los renders. Como tal,job-titlenunca se reemplaza porunemployment-reason, que también es la razón por la que se intercambian los valores predefinidos.Cuando React hace la diferencia, determinará qué componentes son nuevos y cuáles son viejos en función de su
keypropiedad. Si no se proporciona dicha clave en el código, generará la suya propia.La razón por la que el último fragmento de código que proporcionas funciona es porque React esencialmente necesita cambiar la jerarquía de todos los elementos debajo del padre
divy creo que eso desencadenaría una reproducción de todos los hijos (que es la razón por la que funciona). Si hubiera agregado elspanen la parte inferior en lugar de en la parte superior, la jerarquía de los elementos anteriores no cambiaría, y esos elementos no se volverían a representar (y el problema persistiría).Esto es lo que dice la documentación oficial de React :
Debería poder solucionar este problema proporcionando un
keyelemento único usted mismo para el padredivo para todos losMyInputelementos.Por ejemplo:
O
Ahora, cuando React haga la diferencia, verá que
divsson diferentes y lo volverá a renderizar, incluidos todos sus elementos secundarios (primer ejemplo). En el segundo ejemplo, el diff será un éxitojob-titleyunemployment-reasonya que ahora tienen diferentes claves.Por supuesto, puede utilizar las claves que desee, siempre que sean únicas.
Actualización de agosto de 2017
Para tener una mejor idea de cómo funcionan las claves en React, recomiendo encarecidamente leer mi respuesta a Comprender las claves únicas en React.js .
Actualización de noviembre de 2017
Esta actualización debería haberse publicado hace un tiempo, pero el uso de literales de cadena
refahora está en desuso. Por ejemploref="job-title", ahora debería serref={(el) => this.jobTitleRef = el}(por ejemplo). Consulte mi respuesta a la advertencia de obsolescencia usando this.refs para obtener más información.fuente
it will determine which components are new and which are old based on their key property.- eso fue ... clave ... para mi comprensiónCambie la clave del componente.
El componente se desmontará y se montará una nueva instancia de Componente ya que la clave ha cambiado.
editar : Documentado sobre usted probablemente no necesite un estado derivado :
fuente
Úselo
setStateen su vista para cambiar laemployedpropiedad del estado. Este es un ejemplo del motor de renderizado React.fuente
Estoy trabajando en Crud para mi aplicación. Así es como lo hice Got Reactstrap como mi dependencia.
Algunos React Hooks ahí
fuente