Soy bastante nuevo para reaccionar, por lo que sigo entendiendo el ciclo de vida del componente. Pero el problema me ha dejado rascándome la cabeza.
Por ejemplo, no entiendo por qué agregar "setState(10);" hace que el estilo del componente "Prueba" vuelva a su valor predeterminado pero el <div ref={ref2}>Hi</div> mantiene su estilo. (ver imagen a continuación)
Soy consciente de que "setState(10);" provocará una nueva representación, pero ¿por qué se revierte el estilo del componente "Prueba"?
Además, ignore el "uso práctico" de llamar a setState (10). Soy consciente de que no tiene sentido ya que nunca se usa, y soy consciente de que usar "estado" como una dependencia de UseEffect puede resolver este problema. Pero el principal problema que tengo es entender por qué el estilo del componente vuelve a su valor predeterminado.
import React, { useEffect, useState, useRef } from "react"; export default function App() { const [state, setState] = useState(); let ref1 = useRef(); let ref2 = useRef(); useEffect(() => { console.log("useEffect called ", ref1.current); ref1.current.style.backgroundColor = "red"; ref2.current.style.backgroundColor = "green"; setState(10); // }, [state]); }, []); const Test = React.forwardRef((props, ref1) => { console.log("test called - rendering webpage", ref1.current); return ( <div ref={ref1} {...props}> HI from Test{" "} </div> ); }); return ( <div className="App"> <Test ref={ref1} /> <div ref={ref2}>Hi</div> </div> ); }Salida de consola
test called - rendering webpage undefined useEffect called <div style="background-color: red;">HI </div> test called - rendering webpage <div style="background-color: red;">HI </div>import React, { useEffect, useState, useRef } from "react"; export default function App() { const [state, setState] = useState(); let ref1 = useRef(); let ref2 = useRef(); useEffect(() => { console.log("useEffect called ", ref1.current); ref1.current.style.backgroundColor = "red"; ref2.current.style.backgroundColor = "green"; setState(10); // }, [ref.current]); }, [state]); const Test = React.forwardRef((props, ref1) => { console.log("test called - rendering webpage", ref1.current); return ( <div ref={ref1} {...props}> HI from Test{" "} </div> ); }); return ( <div className="App"> <Test ref={ref1} /> <div ref={ref2}>Hi</div> </div> ); }La razón por la que esto sucede es que una vez que actualiza el estado, todo el componente se vuelve a procesar. Su useEffect se ejecutará solo una vez en componentDidMount, por lo tanto, la nueva referencia que obtiene no está actualizada. Para deshacerse de esto, debe usar state como una dependencia de useEffect.
La razón por la que el estilo está desapareciendo es que ha definido su componente Test dentro de su componente de App . Eso significa que cada vez que se renderiza la App , definirá un nuevo tipo de componente llamado Test . El texto de ese componente es idéntico al anterior, pero es un tipo nuevo por lo que reacciona, por lo que reacciona se ve obligado a desmontar el anterior y montar el nuevo. Esto elimina cualquier cambio que haya realizado en el anterior.
Entonces, como mínimo, debe mover Test fuera de la App . De esa manera, el componente solo se define una vez y no se volverá a montar en cada renderizado.
export default App() { // ... } const Test = React.forwardRef((props, ref1) => { // ... })Lo anterior debería arreglar el reinicio y permitirle experimentar con referencias, pero le recomiendo encarecidamente que no use referencias para diseñar sus elementos. Las referencias son una escotilla de escape que a veces se necesita, pero la forma estándar de diseñar un componente es a través de la propiedad de estilo. Si necesita cambiar el estilo, puede tener una variable de estado y dejar que controle la propiedad de estilo.
Si usa javascript manualmente para configurar ref1.current.style.backgroundColor , reaccionar no tiene forma de saber que lo hizo, por lo que no puede tener en cuenta esos cambios. En algunas circunstancias, reaccionar puede terminar sobrescribiendo sus cambios, o puede omitir hacer cambios que no sabe que debe hacer.
export default function App () { const [colored, setColored] = useState(false); useEffect(() => { setColored(true); }, []) return ( <div className="App"> <Test style={colored ? { backgroundColor: "green" } : undefined} /> <div style={colored ? { backgroundColor: "red" } : undefined}>Hi</div> </div> ); } // Don't really need forwardRef anymore, but i left it in const Test = React.forwardRef((props, ref) => { return ( <div ref={ref} {...props}> HI from Test </div> ); });