Cómo usar referencias en React con Typecript

Resuelto Akshar Patel asked hace 9 años • 16 respuestas

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>
    );
}}
Akshar Patel avatar Nov 19 '15 12:11 Akshar Patel
Aceptado

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 refdel atributo currentse asignará al componente/elemento DOM al que se hace referencia y se volverá a asignar nullcuando 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 refdevolución de llamada con el elemento DOM y lo llamará nullcuando se desmonte. Entonces, por ejemplo, puedes acceder a él simplemente usandothis.stepInput .

Al definir la refdevolució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 refatributo 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.

Jeff Bowen avatar May 01 '2017 21:05 Jeff Bowen

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.currentse convierte en una readonlypropiedad inicializando su valor connull .

b) Utilice referencias mutables para valores almacenados arbitrarios similares a variables de instancia:
const FunctionApp = () => {
  const renderCountRef = useRef(0)
  useEffect(() => {
    renderCountRef.current += 1
  })
  // ... other render code
}

Nota: No inicialice useRefcon nullen este caso; crearía el renderCountReftipo readonly(ver ejemplo ). Si necesita proporcionar nullun 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

ford04 avatar May 08 '2020 13:05 ford04

Si está utilizando React.FC, agregue la HTMLDivElementinterfaz:

const myRef = React.useRef<HTMLDivElement>(null);

Y utilícelo de la siguiente manera:

return <div ref={myRef} />;
JulienRioux avatar Mar 30 '2020 19:03 JulienRioux