entonces, lo que estoy tratando de lograr aquí es almacenar un componente completo en una matriz en un componente principal que representa un componente específico en la matriz usando su índice, por ejemplo:
export const Test = () => { const [components, setComponents] = useState([ <Order key={1} />, <Order key={2} />, <Order key={3} />, ]); const [index, setIndex] = useState(0); return ( <div> <button onClick={() => setIndex((old) => (old + 1) % components.length)}> change </button> {`page ` + index} {components[index]} </div> ); }; const Order = () => { const [someState, setSomeState] = useState(1); return ( <div> <button onClick={() => setSomeState((old) => old + 1)}> {someState} </button> </div> ); };cuando cambio el estado de un elemento, luego recorro los elementos y luego vuelvo al elemento cuyo estado cambié, descubrí que no está actualizado
lo que descubrí es que el componente en la matriz (en el componente de prueba) no se actualiza y no pude averiguar cómo actualizarlo
lo que no quiero hacer es almacenar el estado del elemento de pedido en el padre y pasarlo como accesorios (porque será un dolor hacerlo funcionar)
lo que no quiero hacer es almacenar el estado del elemento de pedido en el padre y pasarlo como accesorios (porque será un dolor hacerlo funcionar)
Su problema es que cuando procesa un componente de Test y luego aumenta el índice, luego procesa otro componente de Test con una clave diferente, por lo que el algoritmo de reconciliación reacciona desmonta el anterior y pierde el estado.
Tienes dos opciones:
Test , luego, cuando uno se desmonte, lo volverá a montar con el estado anterior, porque el estado se almacenará en el padre, no se perderádisplay CSS, de esta manera ninguno de ellos se desmonta y conserva el estado. Aquí hay un ejemplo: const Order = () => { const [someState, setSomeState] = React.useState(1); return ( <div> <button onClick={() => setSomeState((old) => old + 1)}> {someState} </button> </div> ); }; let components = [<Order />, <Order />, <Order />]; const Test = () => { const [index, setIndex] = React.useState(0); return ( <div> <button onClick={() => setIndex((old) => (old + 1) % components.length)}> change </button> {`page ` + index} {[0, 1, 2].map((x) => ( <div key={x} style={{ display: index === x ? "block" : "none" }}> {components[x]} </div> ))} </div> ); }; ReactDOM.render( <Test />, document.getElementById("react") ); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="react"></div> PD: He eliminado components del estado, no puedo encontrar información oficial ahora, pero en mi humilde opinión, no es una buena idea almacenar componentes en el estado.
const App = ({ flag }) => { if (flag) <Order /> return null } Te doy un ejemplo para poder explicarte lo que podría pasar en tu caso. Si el indicador pasa a ser false de true , la aplicación se queda en blanco. Pero, ¿qué pasó con la Order ? Está desmontado, ¿por qué? Dado que cuando React compara entre la escena anterior y la escena actual, nota que ya no existe tal Order . Entonces, ¿qué piensas sobre la memoria del componente de Order (que se llama fibra)?
Supongo que la respuesta es que la memoria se eliminará y se recopilará para uso futuro.
Ahora volvamos a su caso, está utilizando una id para cambiar a un componente diferente. Pero en teoría, debería comportarse de manera muy similar a mi ejemplo para cada componente.
NOTA: la conclusión es que si desea usar una matriz, está bien, pero todos los componentes deben renderizarse en TODO momento, puede ocultarlos, pero no puede desmontar ninguno de ellos.