He recreado mi problema en un ejemplo de código simplificado. Sigue estos pasos para reproducirlo:
Ejemplo de código de caja de arena
Tengo una solución poco elegante (solución alternativa) que pondré como respuesta, pero no explica qué o por qué sucede esto. Tengo 3 editores fuera del lienzo como este en mi página y uno funciona como se esperaba, pero los otros dos pierden el estado al llamar a sus funciones de guardado en el padre.
Aquí está mi mala (fea) solución:
Aplicación.js
function open(e, item, itemIndex) { setPropArgs({ ...propArgs, editThis: item, index: itemIndex, show: true, itemList: myList }); }MiEditor.js
<Button type="button" onClick={(e) => props.save(edit, props.index, props.itemList)}> Save </Button>Aplicación.js
function save(edit, index, itemList) { // console.log(myList); const newList = [...itemList]; newList[index] = edit; setMyList(newList); setPropArgs({ ...propArgs, show: false }); }Esto es malo porque MyEditor no debería necesitar saber nada sobre el padre, no lee ni edita la lista en absoluto y no debería ser necesario pasar una copia del estado que podría quedar desactualizado ( si no estuviera bloqueando con la lona).
Vale... Encontré la respuesta que estaba buscando. Gracias a Marco Nisi por esta respuesta a una pregunta muy similar que no ha recibido mucha atención.
Mi solución de código bifurcado aquí
La solución es mover la devolución de llamada (función de guardar) para que se cree cuando se muestra el lienzo en lugar de cuando se inicializa el componente funcional, creando un clon más reciente del estado. Todavía puedo ver que esto es problemático si tiene un ejemplo en el que el estado se actualiza en segundo plano o si el lienzo fuera del lienzo no bloquea otras ediciones. Nota: no necesita la devolución de llamada definida en la función abierta, pero sí debe agregarse (reemplazarse) al objeto de accesorios allí.
function open(e, item, itemIndex) { save = (edit, index) => { console.log(myList); const newList = [...myList]; newList[index] = edit; setMyList(newList); setPropArgs({ ...propArgs, show: false }); }; setPropArgs({ ...propArgs, editThis: item, index: itemIndex, show: true, save: save }); }