[reactjs] Typescript로 React에서 ref를 사용하는 방법

React와 함께 Typescript를 사용하고 있습니다. refs에서 참조하는 반응 노드와 관련하여 정적 타이핑 및 지능을 얻기 위해 refs를 사용하는 방법을 이해하는 데 문제가 있습니다. 내 코드는 다음과 같습니다.

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>
    );
}}



답변

React 16.3 이상을 사용하는 경우 제안 된 참조 생성 방법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} />;
    }
}

구성 요소가 마운트되면 ref속성의 current속성이 참조 된 구성 요소 / DOM 요소에 할당 null되고 마운트 해제시 다시 할당됩니다 . 예를 들어 다음을 사용하여 액세스 할 수 있습니다.this.stepInput.current .

에 대한 자세한 내용은 @apieceofbart의 답변을RefObject 참조 하거나 PR 이 추가되었습니다. createRef()


이전 버전의 React (<16.3)를 사용 중이거나 ref가 설정되고 설정 해제되는시기를보다 세밀하게 제어해야하는 경우 “callback refs”를 사용할 수 있습니다 .

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} />
    }
}

컴포넌트가 마운트되면 React는 refDOM 요소를 사용 하여 콜백을 호출 null하고 마운트 해제시이를 호출합니다 . 예를 들어 간단히 this.stepInput.

ref( 이 답변 의 이전 버전 에서와 같이) 인라인 함수와 반대로 클래스의 바인딩 된 메서드로 콜백 을 정의하면 업데이트 중에 콜백 이 두 번 호출되는 것을 방지 할 수 있습니다.


로 사용 은 An API ref(참조 속성이 문자열였다을 Akshar 파텔의 답변을 ),하지만 인해 몇 가지 문제 , 문자열 심판은 권장하지하고 결국 제거됩니다.


2018 년 5 월 22 일에 React 16.3에서 ref를 수행하는 새로운 방법을 추가하기 위해 편집되었습니다. 새로운 방법이 있음을 지적 해 주신 @apieceofbart에게 감사드립니다.


답변

한 가지 방법 ( 내가했던 )은 수동으로 설정하는 것입니다.

refs: {
    [string: string]: any;
    stepInput:any;
}

그런 다음 더 좋은 getter 함수 (예 : 여기 ) 로이를 래핑 할 수도 있습니다 .

stepInput = (): HTMLInputElement => ReactDOM.findDOMNode(this.refs.stepInput);


답변

React 16.3부터 ref를 추가하는 방법 은 Jeff Bowen이 답변에서 지적한대로 React.createRef 를 사용하는 것입니다. 그러나 Typescript를 활용하여 심판을 더 잘 입력 할 수 있습니다.

귀하의 예에서는 입력 요소에 ref를 사용하고 있습니다. 그래서 그들이 할 방법은 다음과 같습니다.

class SomeComponent extends React.Component<IProps, IState> {
    private inputRef: React.RefObject<HTMLInputElement>;
    constructor() {
        ...
        this.inputRef = React.createRef();
    }

    ...

    render() {
        <input type="text" ref={this.inputRef} />;
    }
}

해당 참조를 사용하고 싶을 때 이렇게하면 모든 입력 방법에 액세스 할 수 있습니다.

someMethod() {
    this.inputRef.current.focus(); // 'current' is input node, autocompletion, yay!
}

사용자 지정 구성 요소에서도 사용할 수 있습니다.

private componentRef: React.RefObject<React.Component<IProps>>;

예를 들어 소품에 대한 액세스 권한이 있습니다.

this.componentRef.current.props; // 'props' satisfy IProps interface


답변

편집 : 이것은 더 이상 Typescript와 함께 ref를 사용하는 올바른 방법이 아닙니다. Jeff Bowen의 답변을보고 찬성하여 가시성을 높입니다.

문제에 대한 답을 찾았습니다. 클래스 내부에서 아래와 같이 refs를 사용하십시오.

refs: {
    [key: string]: (Element);
    stepInput: (HTMLInputElement);
}

올바른 방향을 가리키는 @basarat에게 감사드립니다.


답변

React.createRef (클래스 구성 요소)

class ClassApp extends React.Component {
  inputRef = React.createRef<HTMLInputElement>();

  render() {
    return <input type="text" ref={this.inputRef} />
  }
}

참고 : 여기 에서 이전 String Refs 레거시 API 생략 …


React.useRef (후크 / 기능 부품)

DOM 노드에 대한 읽기 전용 참조 :

const FunctionApp = () => {
  const inputRef = React.useRef<HTMLInputElement>(null) // note the passed in `null` arg
  return <input type="text" ref={inputRef} />
}

임의의 저장된 값에 대한 변경 가능한 참조 :

const FunctionApp = () => {
  const renderCountRef = useRef(0)
  useEffect(() => {
    renderCountRef.current += 1
  })
  // ... other render code
}

참고 : 음주 초기화하지 useRef으로 null이 경우이다. renderCountRef유형 을 만듭니다 readonly( 예제 참조 ). 초기 값 으로 제공 해야하는 경우 다음을 null수행하십시오.

const renderCountRef = useRef<number | null>(null)

콜백 참조 (둘 다 작동)

// Function component example 
const FunctionApp = () => {
  const handleDomNodeChange = (domNode: HTMLInputElement | null) => {
    // ... do something with changed dom node.
  }
  return <input type="text" ref={handleDomNodeChange} />
}

놀이터 샘플


답변

을 사용하는 경우 인터페이스를 React.FC추가하십시오 HTMLDivElement.

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

다음과 같이 사용하십시오.

return <div ref={myRef} />;


답변

React 문서에서 권장 하는 콜백 스타일 ( https://facebook.github.io/react/docs/refs-and-the-dom.html ) 을 사용하려면 클래스에 속성에 대한 정의를 추가 할 수 있습니다.

export class Foo extends React.Component<{}, {}> {
// You don't need to use 'references' as the name
references: {
    // If you are using other components be more specific than HTMLInputElement
    myRef: HTMLInputElement;
} = {
    myRef: null
}
...
 myFunction() {
    // Use like this
    this.references.myRef.focus();
}
...
render() {
    return(<input ref={(i: any) => { this.references.myRef = i; }}/>)
}