Cómo usar referencias en React con Typecript
Estoy usando Typecript con React. Tengo problemas para entender cómo usar las referencias para obtener escritura estática e inteligencia con respecto a los nodos de reacción a los que hacen referencia las referencias. Mi código es el siguiente.
import * as React from 'react';
interface AppState {
count: number;
}
interface AppProps {
steps: number;
}
interface AppRefs {
stepInput: HTMLInputElement;
}
export default class TestApp extends React.Component<AppProps, AppState> {
constructor(props: AppProps) {
super(props);
this.state = {
count: 0
};
}
incrementCounter() {
this.setState({count: this.state.count + 1});
}
render() {
return (
<div>
<h1>Hello World</h1>
<input type="text" ref="stepInput" />
<button onClick={() => this.incrementCounter()}>Increment</button>
Count : {this.state.count}
</div>
);
}}
Si estás usando React 16.3+, la forma sugerida de crear referencias es usar React.createRef()
.
class TestApp extends React.Component<AppProps, AppState> {
private stepInput: React.RefObject<HTMLInputElement>;
constructor(props) {
super(props);
this.stepInput = React.createRef();
}
render() {
return <input type="text" ref={this.stepInput} />;
}
}
Cuando el componente se monta, la propiedad ref
del atributo current
se asignará al componente/elemento DOM al que se hace referencia y se volverá a asignar null
cuando se desmonte. Entonces, por ejemplo, puedes acceder a él usandothis.stepInput.current
.
Para obtener más información RefObject
, consulte la respuesta de @apieceofbart o se agregó el PR . createRef()
Si está utilizando una versión anterior de React (<16.3) o necesita un control más detallado sobre cuándo se configuran y desactivan las referencias, puede usar "referencias de devolución de llamada" .
class TestApp extends React.Component<AppProps, AppState> {
private stepInput: HTMLInputElement;
constructor(props) {
super(props);
this.stepInput = null;
this.setStepInputRef = element => {
this.stepInput = element;
};
}
render() {
return <input type="text" ref={this.setStepInputRef} />
}
}
Cuando el componente se monte, React llamará a la ref
devolución de llamada con el elemento DOM y lo llamará null
cuando se desmonte. Entonces, por ejemplo, puedes acceder a él simplemente usandothis.stepInput
.
Al definir la ref
devolución de llamada como un método vinculado en la clase en lugar de una función en línea (como en una versión anterior de esta respuesta), puede evitar que se llame a la devolución de llamada dos veces durante las actualizaciones.
Solía haber una API donde el ref
atributo era una cadena (consulte la respuesta de Akshar Patel ), pero debido a algunos problemas , se desaconsejan las referencias de cadena y eventualmente se eliminarán.
Editado el 22 de mayo de 2018 para agregar la nueva forma de hacer referencias en React 16.3. Gracias @apieceofbart por señalar que había una nueva forma.
React.createRef
(comp. de clase)
class ClassApp extends React.Component {
inputRef = React.createRef<HTMLInputElement>();
render() {
return <input type="text" ref={this.inputRef} />
}
}
React.useRef
(Ganchos / función comp.)
a) Utilice referencias de solo lectura para nodos DOM administrados por React:
const FunctionApp = () => {
// note the passed-in `null` arg ----------------v
const inputRef = React.useRef<HTMLInputElement>(null)
return <input type="text" ref={inputRef} />
}
inputRef.current
se convierte en una readonly
propiedad inicializando su valor connull
.
const FunctionApp = () => {
const renderCountRef = useRef(0)
useEffect(() => {
renderCountRef.current += 1
})
// ... other render code
}
Nota: No inicialice useRef
con null
en este caso; crearía el renderCountRef
tipo readonly
(ver ejemplo ). Si necesita proporcionar null
un valor inicial, haga esto:
const renderCountRef = useRef<number | null>(null)
Referencias de devolución de llamada (ambas)
// Function component example, class analogue
const FunctionApp = () => {
const handleDomNodeChange = (domNode: HTMLInputElement | null) => {
// ... do something with changed dom node.
}
return <input type="text" ref={handleDomNodeChange} />
}
Nota: Las referencias de cadena se consideran heredadas y se omiten en el alcance de esta respuesta.
Muestra de patio de recreo
Si está utilizando React.FC
, agregue la HTMLDivElement
interfaz:
const myRef = React.useRef<HTMLDivElement>(null);
Y utilícelo de la siguiente manera:
return <div ref={myRef} />;