[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는 ref
DOM 요소를 사용 하여 콜백을 호출 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; }}/>)
}