vida react qué que podemos optimizar método helmet desmontar con componentes componente componentdidmount ciclo change javascript reactjs

javascript - qué - ¿Cómo forzar el montaje en los componentes React?



react meta tags (3)

Cambiar la clave del componente.

<Component key="1" />

<Component key="2" />

Component se desmontará y se montará una nueva instancia de Component ya que la clave ha cambiado.

editar : Documentado en usted probablemente no necesita estado derivado :

Cuando una clave cambia, React creará una nueva instancia de componente en lugar de actualizar la actual. Las claves se usan generalmente para listas dinámicas, pero también son útiles aquí.

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 employed es cierto. Cada vez que lo cambio a falso y se muestra la otra vista, solo se reinicia la unemployment-duration . También unemployment-reason se llena previamente con el valor del job-title del job-title (si se dio un valor antes de que la condición cambiara).

Si cambio el marcado en la segunda rutina de representación 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 no logra diferenciar el "título del trabajo" y la "razón del desempleo".

Por favor dime que estoy haciendo mal ...


Lo que probablemente está sucediendo es que React piensa que solo se MyInput un MyInput ( unemployment-duration ) entre los renders. Como tal, el job-title del job-title nunca se reemplaza con el unemployment-reason del unemployment-reason , que también es la razón por la cual se intercambian los valores predefinidos.

Cuando React haga la diferencia, determinará qué componentes son nuevos y cuáles son antiguos en función de su propiedad key . Si no se proporciona dicha clave en el código, generará la suya.

La razón por la cual el último fragmento de código que proporcionó funciona es porque React esencialmente necesita cambiar la jerarquía de todos los elementos bajo el div principal y creo que eso desencadenaría una nueva representación de todos los elementos secundarios (por eso funciona). Si hubiera agregado el span en 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 procesar (y el problema persistiría).

Esto es lo que dice la documentación oficial de React :

La situación se vuelve más complicada cuando los niños se barajan (como en los resultados de búsqueda) o si se agregan nuevos componentes al principio de la lista (como en las transmisiones). En estos casos en los que la identidad y el estado de cada niño deben mantenerse a través de los pases de representación, puede identificar de manera única a cada niño asignándole una clave.

Cuando React reconcilie a los niños con clave, se asegurará de que cualquier niño con clave se reordene (en lugar de golpearse) o se destruya (en lugar de reutilizarse).

Debería poder solucionar esto proporcionando usted mismo un elemento key único para el div principal o para todos los elementos MyInput .

Por ejemplo:

render(){ if (this.state.employed) { return ( <div key="employed"> <MyInput ref="job-title" name="job-title" /> </div> ); } else { return ( <div key="notEmployed"> <MyInput ref="unemployment-reason" name="unemployment-reason" /> <MyInput ref="unemployment-duration" name="unemployment-duration" /> </div> ); } }

O

render(){ if (this.state.employed) { return ( <div> <MyInput key="title" ref="job-title" name="job-title" /> </div> ); } else { return ( <div> <MyInput key="reason" ref="unemployment-reason" name="unemployment-reason" /> <MyInput key="duration" ref="unemployment-duration" name="unemployment-duration" /> </div> ); } }

Ahora, cuando React haga la diferencia, verá que los divs son diferentes y lo volverá a representar incluyendo a todos sus ''hijos'' (primer ejemplo). En el segundo ejemplo, la diferencia será un éxito en job-title unemployment-reason ya que ahora tienen claves diferentes.

Por supuesto, puede usar las teclas que desee, siempre que sean únicas.

Actualización de agosto de 2017

Para una mejor comprensión de cómo funcionan las claves en React, recomiendo leer mi respuesta a Comprender 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 en ref ahora está en desuso. Por ejemplo, ref="job-title" ahora debería ser ref={(el) => this.jobTitleRef = el} (por ejemplo). Consulte mi respuesta a la Advertencia de desaprobación con this.refs para obtener más información.


Use setState en su vista para cambiar la propiedad de estado employed . Este es un ejemplo del motor de procesamiento React.

someFunctionWhichChangeParamEmployed(isEmployed) { this.setState({ employed: isEmployed }); } getInitialState() { return { employed: true } }, 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> ); } }