Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

98
Views
La matriz de componentes no se actualiza cuando cambian los accesorios

Enlace de Codesandbox

Tengo dos componentes, un padre y un hijo. Los componentes principales mantienen una lista de elementos secundarios en estado y la representan mediante el método de mapa.

El padre:

 import { useState } from "react";
import Child from "./Child";

export default function Parent(){
 const [counter, setCounter] = useState(0)
 const [childKey, setChildKey] = useState(0);
 const [children, setChildren] = useState([]);

 function addChild(){
 setChildren([...children, <Child counter={counter} index={childKey}/>]);
 setChildKey(childKey + 1);
 }

 return (
 <>
 <h2>The parent component</h2>
 <p>The counter is set to {counter}</p>
 <p><button onClick={() => {setCounter(counter + 1)}}>Increment</button></p>
 <p><button onClick={addChild}>Add child</button></p>

 {children.map((c, i) => {
 return (
 <div key={i}>{c}</div>
 );
 })}
 
 </>
 );
}

El niño:

 export default function Child({counter, index}){
 return (
 <>
 <p>Child {index}: the counter is set to {counter}</p>
 </>
 );
}

Al hacer clic en el botón "agregar niño", se agrega un niño a la matriz de niños.

Al hacer clic en el botón "incrementar", se actualiza el contador en el padre, pero el contador en los hijos no cambia.

¿Hay alguna manera de volver a representar a los niños cuando el contador aumenta? (mientras que es preferible mantener a los niños en una matriz)

Enlace de Codesandbox

almost 4 years ago · Santiago Trujillo
3 answers
Answer question

0

setChildren([...children, <Child counter={counter} index={childKey}/>]);

No ponga elementos en estado. Hace que sea muy fácil tener errores como el que tienes ahora. Efectivamente, ha "bloqueado" cuáles son los accesorios para el niño, por lo que los cambios en el contador no surtirán efecto.

En su lugar, simplemente almacene los datos mínimos que se necesitan para crear los elementos y luego cree esos elementos durante el renderizado. En su caso, creo que solo necesita un número que indique cuántos niños representar. Convenientemente, ya tienes eso en childKey , así que recomiendo:

 export default function Parent(){
 const [counter, setCounter] = useState(0)
 const [childKey, setChildKey] = useState(0);

 const children = [];
 for (let i = 1; i <= childKey; i++) {
 children.push((
 <div key={i}>
 <Child counter={counter} index={i} />
 </div>
 ));
 }

 function addChild(){
 setChildKey(childKey + 1);
 }

 return (
 <>
 <h2>The parent component</h2>
 <p>The counter is set to {counter}</p>
 <p><button onClick={() => {setCounter(counter + 1)}}>Increment</button></p>
 <p><button onClick={addChild}>Add child</button></p>

 {children}
 
 </>
 );
}

Tal vez childKey podría cambiarse de nombre a childCount .

almost 4 years ago · Santiago Trujillo Report

0

Cuando tu lo hagas:

 setChildren([...children, <Child counter={counter} index={childKey}/>]);

Le dices a React que agregue el elemento <Child counter={counter} index={childKey}/> al estado de los children . Crea un elemento con el counter de accesorios y childKey con los valores que tienen en el momento en que los agrega al estado. Volver a representar estos elementos con un valor diferente para childKey no tendrá ningún impacto.

Dependiendo de lo que quieras hacer, hay muchas soluciones. Si desea renderizar Child con el valor de counter en el momento de volver a renderizar, haría algo como esto:

 export default function Parent(){
 const [counter, setCounter] = useState(0)
 const [childKey, setChildKey] = useState(0);
 const [children, setChildren] = useState([]);

 function addChild(){
 setChildren([...children, ({ counter }) => <Child counter={counter} index={childKey}/>]);
 setChildKey(childKey + 1);
 }

 return (
 <>
 <h2>The parent component</h2>
 <p>The counter is set to {counter}</p>
 <p><button onClick={() => {setCounter(counter + 1)}}>Increment</button></p>
 <p><button onClick={addChild}>Add child</button></p>

 {children.map((childFn, i) => {
 return (
 <div key={i}>{childFn({ counter })}</div>
 );
 })}
 
 </>
 );
}

O puede ser más simple (y menos propenso a errores):

 export default function Parent(){
 const [counter, setCounter] = useState(0)
 const [childKey, setChildKey] = useState(0);
 const [children, setChildren] = useState([]);

 function addChild(){
 setChildren([...children, childKey]);
 setChildKey(childKey + 1);
 }

 return (
 <>
 <h2>The parent component</h2>
 <p>The counter is set to {counter}</p>
 <p><button onClick={() => {setCounter(counter + 1)}}>Increment</button></p>
 <p><button onClick={addChild}>Add child</button></p>

 {children.map((childKey, i) => {
 return (
 <div key={i}><Child counter={counter} index={childKey} /></div>
 );
 })}
 
 </>
 );
}
almost 4 years ago · Santiago Trujillo Report

0

Sí, como otras respuestas, mantener los componentes en estado no es una buena idea, bien explicado por Nicholas arriba

Misma respuesta pero diferente estilo de rendering 😛

Acabo de actualizar Parent.js como se muestra a continuación

 import { useState } from "react";
import Child from "./Child";

export default function Parent() {
 const [counter, setCounter] = useState(0);
 const [childKey, setChildKey] = useState(0);

 function addChild() {
 setChildKey(childKey + 1);
 }

 return (
 <>
 <h2>The parent component</h2>
 <p>The counter is set to {counter}</p>
 <p>
 <button
 onClick={() => {
 setCounter(counter + 1);
 }}
 >
 Increment
 </button>
 </p>
 <p>
 <button onClick={addChild}>Add child</button>
 </p>
 {/* create an array of length of childKey number */}
 {Array.from({ length: childKey }, (_, i) => {
 return <Child key={i} counter={counter} index={i} />;
 })}
 </>
 );
}
almost 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!