React.createRef() API 대신 callback ref를 대신 사용하기React.createRef()를 사용하여 생성하고, ref attrubute를 통해 React element에 부착됨class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
render() {
return <div ref={this.myRef} />;
}
}
render 메서드 안에서 ref가 element에 전달되었을 때, 그 노드를 향한 참조는 ref의 current attribute에 담김const node = this.myRef.current;
ref attribute가 HTML element에 사용되었을 떄, constructor에서 React.createRef()로 생성된 ref는 자신을 전달 받은 DOM element를 current property값으로 받음ref attribute가 커스텀 클래스 컴포넌트에 사용되었을 때, ref 객체는 마운트된 컴포넌트의 인스턴스를 current property값으로 받음ref attribute를 사용할 수 없음class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// textInput DOM Element를 저장하기 위한 ref 생성
this.textInput = React.createRef();
this.focusTextInput = this.focusTextInput.bind(this);
}
focusTextInput() {
// DOM 노드를 얻기 위해 'current' property에 접근함
this.textInput.current.focus();
}
render() {
return (
{/* constructor에서 생성한 'textInput'과 <input> ref를 연결함 */}
<input
type="text"
ref={this.textInput} />
<input
type="button"
ref={this.focusTextInput} />
)
}
}
current property에 DOM Element를 할당함current 프로퍼티는 다시 null이 됨componentDidMount(첫 렌더링 완료 이후 실행) 또는 componentDidUpdate(리렌더링 완료 이후 실행) 생명주기 메서드가 호출되기 전 ref가 업데이트됨class AutoFocusTextInput extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
componentDidMount() {
this.textInput.current.focusTextInput();
}
render() {
return (
<CustomTextInput ref={this.textInput} />
)
}
}
function MyFunctionComponent() {
return <input />;
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.textInput = React.createRef();
}
render() {
// 이 코드는 동작하지 않음
return (
<MyFunctionComponent ref={this.textInput} />
)
}
}

부모 컴포넌트에서 자식 컴포넌트의 DOM 노드에 접근하기를 원할 수 있음
자식 컴포넌트에 ref를 추가하는 것은 좋은 방법이 아님
React 16.3 이상 버젼을 사용하는 경우, ref forwarding을 사용하는 것이 좋음
Ref forwarding은 컴포넌트가 자식 컴포넌트의 ref를 자신의 ref로서 외부에 노출시킴React 16.2나 더 낮은 버젼을 사용하는 경우, ref를 명시적으로 다른 이름의 prop으로 전달하여 사용할 수 있음
자식 컴포넌트 수행의 권한이 없다면, 마지막 방법은 findeDOMNode()를 사용하는 것이나 권장하지 않으며 StrictMode에서 이 메서드는 없어졌음
ref callback을 사용하여 인스턴스의 property에 DOM 노드의 참조를 저장할 수 있음function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
render() {
return (
<CustomTextInput
inputRef={el => this.inputElement = el} />
)
}
}
ref attribute에 ref callback을 전달함ref callback이 인라인 함수로 정의되어 있으면, ref callback은 업데이트 과정 중 처음에는 null로 다음에는 DOM Element로 총 두 번 호출됨ref callback의 새로운 인스턴스가 생성됨ref callback을 클래스에 바인딩된 메서드로 정의함으로서 이러한 현상에서 벗어날 수 있음const refContainer = useRef(initialValue);
useRefcurrent property를 가진 변경 가능한 ref 객체를 반환함uesRef는 자식 컴포넌트에 직접적으로 접근할 때 주로 사용됨function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focust();
}
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
React에 ref 객체를 전달하면, React는 노드가 바뀔 때 마다 ref의 current propery로 대응되는 DOM 노드를 설정함
useRef()는 JavaScirpt 객체를 생성하기 때문에 변하는 값을 저장할 수 있음
callback ref를 대신 사용하기const SimpleCallbackRef = () => {
let inputRef: HTMLInputElement | null;
const onClick = () => {
console.log('INPUT VALUE: ', inputRef?.value);
}
const onFocusClick = () => {
console.log('Focus input');
inputRef?.focus();
}
console.log('Rendering')
return (
<div>
<input ref={node => { inputRef = node; }} />
<button onClick={onClick}>Log value</button>
<button onClick={onFocusClick}>Focus on input</button>
</div>
);
};
React.forwardRef는 전달받은 ref attribute를 하위 트리의 다른 컴포넌트에 전달하는 React 컴포넌트를 생성함React.forwardRef 사용 예import React from 'react';
type ForwardedInputProps = {
placeholder?: string
};
const ForwardedInput = React.forwardRef<HTMLInputElement, ForwardedInputProps>(({ placeholder }, ref) => (
<input ref={ref} placeholder={placeholder} />
));
const SimpleForwardRef = () => {
const inputRef = React.useRef<HTMLInputElement>(null);
const selectText = () => {
inputRef.current?.select();
}
return (
<div>
<ForwardedInput ref={inputRef} placeholder="Type here"/>
<button onClick={selectText}>Select text</button>
</div>
);
};
React.forwardRef를 사용해서 전달 받은 ref를 DOM input에 내려줌| State | Ref | |
|---|---|---|
| 공통점 | 컴포넌트 라이프 사이클 내 유지됨, 값 변경 가능 | 컴포넌트 라이프 사이클 내 유지됨, 값 변경 가능 |
| 차이점 | 값 변경시 리렌더링됨 | 값 변경시 리렌더링 안 됨 |
| createRef | useRef | |
|---|---|---|
| 공통점 | ref를 생성함 | ref를 생성함 |
| 차이점 | 리렌더링시 새 ref를 생성함 | 리렌더링시 같은 ref를 사용함 |