Tengo un componente funcional que causa el siguiente error:
null no es un objeto (evaluando 'textInput.current.blur'
me pregunto porque
import React, { useState, useRef } from "react"; import { TextInput } from "react-native"; const UselessTextInput = ({ hide }) => { const [text, onChangeText] = React.useState("Useless Text"); const textInput = useRef(null); const _renderInput = () => { if (hide) textInput.current.blur(); <TextInput ref={textInput} onFocus={() => ...} onChangeText={onChangeText} value={text} /> ... return __renderInput(); }¿Alguien puede explicar este comportamiento?
Si establece una referencia a un nodo DOM usando el atributo ref , la propiedad current de la referencia tendrá ese nodo solo después de que se establezca, es decir, en las devoluciones de llamada de useEffect o de los próximos renderizados.
function Counter() { const [count, setCount] = React.useState(0); const divRef = React.useRef("initval"); console.log("During Render", divRef.current); React.useEffect(() => { console.log("Inside useEffect CB", divRef.current); }, []); return <button ref={divRef} onClick={() => setCount(count + 1)}>{count}</button>; } ReactDOM.render(<Counter />, document.getElementById("root")); <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div id="root"></div>Entendiendo el flujo:
Cuando se llama useRef , React devuelve un objeto cuya propiedad current se establece en el valor inicial proporcionado ( "initval" en nuestro caso).
Entonces, el registro de la consola durante el primer renderizado imprime el valor inicial.
Luego, el JSX se devuelve desde el componente, que actualiza la referencia y establece su propiedad current en el nodo DOM.
Luego, la devolución de llamada pasó las ejecuciones useEffect y, dado que la referencia ya se ha actualizado, imprime el nodo DOM.
Luego, en el siguiente renderizado (que se puede activar haciendo clic en el botón), nuevamente llamamos a useRef y React devuelve el mismo objeto y, por lo tanto, esta vez el registro durante el renderizado imprime el nodo DOM.
use el encadenamiento opcional a su textInput de entrada de texto
así: textInput?.current?.blur();