React
Preservar y reiniciar estado
Explica cómo la posición, el tipo y la key controlan si React conserva o reinicia el estado local de un componente entre renderizados.
- Última actualización
- Actualizada
- Nivel
- Fundamentos
React
Explica cómo la posición, el tipo y la key controlan si React conserva o reinicia el estado local de un componente entre renderizados.
React no guarda estado “dentro de la función” como una variable normal. Lo asocia con la instancia que ocupa una posición concreta.
function App() {
return show ? <Counter /> : <Counter />;
}Aunque existan dos ramas, si producen el mismo tipo en la misma posición, React puede preservar el contador.
<Chat key={selectedUser.id} user={selectedUser} />Cambiar la key reinicia inputs, refs y estado local. Es útil cuando el nuevo dato representa una identidad diferente.
const [name, setName] = useState(user.name);El inicializador solo se usa al montar. Si user cambia, name no se actualiza automáticamente. Decide si quieres preservar borradores o reiniciar por key.
Antes de escribir un effect para reiniciar estado, revisa si la identidad del componente debería cambiar.
React no almacena el estado dentro del archivo ni dentro de la función como una variable normal. Lo asocia con una instancia identificada por su posición, tipo y key dentro del árbol.
posición + tipo + key
↓
identidad de componente
↓
state + refs + effectsMientras esa identidad se mantenga, el estado puede conservarse aunque cambien props o el componente vuelva a renderizar.
function ContactEditor({ contact }: { contact: Contact }) {
const [name, setName] = useState(contact.name);
// ...
}Si el padre cambia de contacto pero mantiene la misma instancia, el borrador anterior continúa. React no sabe si el nuevo objeto representa una identidad diferente o una actualización del mismo formulario.
Debes decidir la semántica del producto:
Útil cuando el usuario cambia temporalmente de vista y luego regresa al mismo proceso.
<ContactEditor key={contact.id} contact={contact} />La key comunica que cada contacto necesita una instancia independiente.
<ContactEditor
name={draft.name}
onNameChange={(name) => setDraft((current) => ({ ...current, name }))}
/>El padre se convierte en la fuente de verdad y decide cuándo limpiar o sustituir el dato.
No todas las técnicas de ocultamiento tienen la misma semántica.
{isOpen && <Panel />}Al pasar a false, el panel se desmonta y pierde su estado local.
<div hidden={!isOpen}>
<Panel />
</div>El panel continúa montado; conserva state, refs y effects.
<Activity mode={isOpen ? "visible" : "hidden"}>
<Panel />
</Activity>En entornos compatibles, Activity permite preservar estado mientras React reduce la actividad de la región oculta. No equivale a CSS ni a desmontar.
También puedes colocar componentes en posiciones distintas:
{isCompany ? (
<CompanyForm />
) : (
<PersonalForm />
)}Como los tipos son diferentes, React crea otra instancia. Pero depender de estructuras difíciles de leer solo para reiniciar puede volver frágil el diseño. Una key explícita comunica mejor la intención cuando el tipo visual es el mismo.
Una key reinicia todo el subárbol:
Puede ser demasiado agresivo si solo quieres limpiar un campo.
Para un reset parcial, actualiza el estado responsable:
setDraft((current) => ({ ...current, comment: "" }));Usa key cuando la identidad completa cambió, no como sustituto de diseñar transiciones.
function NewTaskForm() {
const [version, setVersion] = useState(0);
async function handleCreated() {
setVersion((current) => current + 1);
}
return <TaskFields key={version} onCreated={handleCreated} />;
}Esto puede limpiar toda la instancia después de un éxito. Sin embargo, para formularios controlados suele ser más claro restablecer el estado explícitamente; una Action también puede resetear campos no controlados según el flujo.
Reiniciar una instancia puede eliminar el nodo enfocado. Antes de cambiar una key considera:
Una decisión técnicamente correcta puede ser una mala experiencia si destruye un borrador sin aviso.
Cuando el estado se conserva inesperadamente:
Cuando el estado se pierde inesperadamente:
useState?hidden, render condicional y Activity?hidden mantiene montado; el condicional desmonta; Activity puede preservar con actividad reducida.useState explica cómo una instancia recuerda información y cómo diseñar actualizaciones sin crear estados redundantes.