Considere la siguiente matriz de objetos:
const tasks = [ { text: "Finish this page", deadline: new Date("05/01/2022"), status: "complete", // ToDo: Add priority fields }, { text: "Finish Pierian UI/UX", deadline: new Date("05/10/2022"), status: "incomplete", }, { text: "Finish Internship", deadline: new Date("05/05/2022"), status: "incomplete", }, { text: "Anaadyanta", deadline: new Date("05/12/2022"), status: "incomplete", }, { text: "Random task", deadline: new Date("05/19/2022"), status: "incomplete", }, ];Considere la siguiente función:
{tasks.map((element) => { return ( <p key={element.name} className={element.status === "complete" && "strike"} style={{ borderLeft: "2px solid red" }}> <Checkbox size="small" onClick={() => { if (element.status === "incomplete") element.status = "complete"; else if (element.status === "complete") { element.status = "incomplete"; } // ToDo : Add few things like popping }} color="success" checked={element.status === "complete" && true} /> {element.text} </p> ); })} Ahora, dado que element.status no es un estado, cambiar su valor no vuelve a representar el elemento JSX. ¿Cómo logro esto? Pensé en usar una variable de estado, pero que cuando se cambiara reflejaría los cambios en todos los elementos renderizados y no solo en el elemento actual.
No puedes, al menos, no en el buen sentido. La forma en que React determina cuándo necesita volver a renderizar es cuando se llama a un setter de estado.
Una aplicación React debe, siempre que sea posible, hacer que la apariencia de la aplicación provenga tanto del estado como sea posible. Es decir, idealmente, dado el estado de todos los componentes, debería poder determinar todo sobre lo que se representa para el usuario.
Pensé en usar una variable de estado, pero que cuando se cambiara reflejaría los cambios en todos los elementos renderizados y no solo en el elemento actual.
¿Por qué cambiaría necesariamente todos los elementos? Simplemente cambie el elemento que se está iterando. Para facilitar las cosas, use complete: boolean en lugar de status: 'complete' | 'incomplete' .
const [tasks, setTasks] = useState([ { text: "Finish this page", deadline: new Date("05/01/2022"), complete: true // ToDo: Add priority fields }, // ... ]); // ... {tasks.map((element, i) => { ... onClick={() => { setTasks(tasks.map( (task, j) => i === j ? { ...task, complete: !element.complete } : task ); }}