Tengo un cuadro de diálogo modal con pestañas y en una de mis pestañas estoy representando dos componentes de la lista de imágenes. Cada componente administra una matriz de objetos de imagen en función de algunos accesorios que se definen en el padre. En mi cuadro de diálogo, tengo un solo botón Guardar y necesito llamar a la API de back-end para actualizar o eliminar cualquier estado de imagen de cualquiera de los componentes de la lista de imágenes. Por ejemplo
function MyItem() { function handleSave() { // How would I get the state from my ImageList components? } //other handlers return ( <TabPanel index={0} title="Detail"> <HeaderWithSaveButton onSaveClick={handleSave} /> <SomeTextContent/> </TabPanel> <TabPanel index={1} title="Images"> <ImageList key="banner" /> <ImageList key="icon" /> </TabPanel> ) }
Los componentes de ImageList mantienen su propio estado en una matriz sobre las imágenes que se agregan o eliminan.
function ImageList({key}) { const [images, setImages] = useState([{imageKey: key, url:`/images/${key}`, fileData: null}]) function handleImageSelected(image){ setImages() // add image } // other handlers return ( <ImageUploader/> <SortedImageList images={images} /> ) }
Tengo la lista de imágenes en funcionamiento, pero obviamente el estado es local para cada una, por lo que no tengo forma de acceder a ella en el botón Guardar del elemento primario en el componente Elemento.
¿Es esto algo para lo que puedo usar Contexto? ¿Tendría que haber dos contextos que se fusionarán? Si elevo el estado hasta el componente Item, ¿cómo realizaría un seguimiento de ambas matrices? Además, el componente del artículo ya se está hinchando.
Pero la pregunta básica es un enfoque para administrar el estado en las dos listas de imágenes y acceder a él en el padre para poder averiguar qué se debe enviar a la API cuando se guardan.
Puede pasar una función de actualización de estado a cada componente para permitirles actualizar el estado de su padre. No estoy seguro de si esta es una forma particularmente 'React-y' de hacerlo, pero algo como:
function MyItem() { const [imageState, setImageState] = useState({}); function handleSave() { // Use imageState to access the images } //other handlers return ( <TabPanel index={0} title="Detail"> <HeaderWithSaveButton onSaveClick={handleSave} /> <SomeTextContent/> </TabPanel> <TabPanel index={1} title="Images"> <ImageList key="banner" setImageState={setImageState} /> <ImageList key="icon" setImageState={setImageState} /> </TabPanel> ) }
Y luego su componente ImageList puede usar el setter de estado pasado para informar al componente principal:
function ImageList({key, setImageState}) { const [images, setImages] = useState([{imageKey: key, url:`/images/${key}`, fileData: null}]) function handleImageSelected(image){ setImages() // add image setImageState((current) => { return { ...current, [key]: image, } }) } // other handlers return ( <ImageUploader/> <SortedImageList images={images} /> ) }
La otra solución es 'elevar' el estado al componente principal