리액트에서는 Ref라는 기능을 사용해 컴포넌트 내부의 특정 DOM에 직접 접근할 수 있다.
Ref는 "reference"의 약자로, 리액트에서 특정 DOM 엘리먼트나 컴포넌트 인스턴스에 접근하는 방법을 제공한다. Ref를 이용하면 직접적인 DOM 조작이 가능해져 특정 요소에 포커스를 주거나, 크기 또는 위치를 계산 하는 일이나, 미디어의 재생을 제어하는 등의 작업을 할 수 있다.
함수형 컴포넌트에서는 useRef
훅을 사용해 Ref를 생성하고 관리한다. 이 훅은 렌더링 사이에서 Ref 객체의 current
값을 유지해주기 때문에, 렌더링이 일어나더라도 Ref 값은 변하지 않는다.
예를 들어, 입력 필드에 사용자가 클릭한 시점에 자동으로 포커스를 주고 싶다면 다음과 같이 useRef
를 사용할 수 있다:
import React, { useRef } from 'react';
function MyComponent() {
const myInput = useRef();
const handleClick = () => {
myInput.current.focus();
};
return (
<div>
<input ref={myInput} />
<button onClick={handleClick}>Focus the input</button>
</div>
);
}
위 예제에서 useRef
훅은 입력 엘리먼트에 대한 참조를 저장하고, 버튼이 클릭되면 해당 참조를 통해 입력 엘리먼트에 직접 포커스를 준다. Ref는 사용하기 쉬운 동시에 강력한 기능을 제공하므로, 적절한 상황과 케이스에서 활용해야 하며 그렇지 않으면 복잡도를 높일 수 있다는 점을 유념해야 한다.
forward Ref는 리액트에서 Ref를 직접 다루기 보다, 자식 컴포넌트로 Ref를 "전달"하기 위한 기능이다. 즉, 부모 컴포넌트가 자식 컴포넌트의 내부 DOM 엘리먼트에 직접 접근할 필요가 있을 때 사용할 수 있다.
forward Ref를 사용하는 것은 큰 컴포넌트 트리에서 특정 자식 컴포넌트의 DOM 엘리먼트에 접근해야 할 때 유용하다. 이를 통해 부모 컴포넌트가 자식 컴포넌트의 내부 구조나 동작 방식을 알 필요 없이 필요한 작업을 수행할 수 있다.
리액트의 React.forwardRef
함수를 사용하면 forward Ref를 생성할 수 있다. 아래 예시는 MyInput
컴포넌트가 ref
를 받아서 내부의 input
엘리먼트로 전달하는 모습을 보여준다.
const MyInput = forwardRef((props, ref) => (
<input ref={ref} type="text" {...props} />
));
function ParentComponent() {
const inputRef = useRef();
return (
<div>
<MyInput ref={inputRef} />
<button
onClick={() => {
alert(inputRef.current.value);
inputRef.current.value = "";
inputRef.current.focus();
}}
>포커스</button>
</div>
);
}
이 예제에서 React.forwardRef
를 사용해 MyInput
컴포넌트는 받은 ref
를 내부 input
엘리먼트에 전달한다. 부모 컴포넌트는 MyInput
컴포넌트의 내부 구조나 동작을 알 필요 없이 input
엘리먼트에 직접 접근할 수 있다.
forward Ref는 컴포넌트 설계에서 중요한 역할을 하며, 컴포넌트 간의 느슨한 결합을 유지하면서도 필요한 경우 특정 DOM 조작을 할 수 있게 해준다.
mutable object Ref는 React의 useRef
훅을 사용하여 만들 수 있으며, 이 객체는 .current
프로퍼티를 가지고 있다. 이 프로퍼티는 변경 가능하며, 컴포넌트 렌더링 사이에서 값을 유지한다. 이는 값을 저장하고 관리하고 싶을 때 유용하다.
다음은 mutable object Ref를 사용하는 간단한 예시다.
import React, { useRef } from 'react';
function MyComponent() {
const myRef = useRef(0); // 초기값 설정
const handleClick = () => {
myRef.current += 1; // current 값 변경
console.log(myRef.current); // 변경된 값 로깅
};
return (
<button onClick={handleClick}>
Click me
</button>
);
}
여기서 useRef
를 사용하여 myRef
라는 mutable object Ref를 생성하고, .current
프로퍼티를 통해 값에 접근하고 수정한다. myRef.current
의 값은 컴포넌트가 다시 렌더링되어도 유지되므로, 컴포넌트의 상태나 생명 주기와 독립적인 값을 관리하고 싶을 때 사용할 수 있다.
이런 성질 때문에 mutable object Ref는 DOM 요소의 참조뿐만 아니라, 타이머 ID, 외부 라이브러리의 인스턴스 등과 같이 컴포넌트 렌더링과 무관한 값을 관리하는 데 사용될 수 있다.
mutable object Ref를 사용하면 값의 변경이 컴포넌트의 재렌더링을 유발하지 않기 때문에, 렌더링과 무관한 값을 효율적으로 관리할 수 있다는 장점이 있다.
이 방법은 리액트에서 값을 다루는 또 다른 유연한 방식으로, 상황에 맞게 적절하게 활용할 수 있어야 한다.
callback Ref는 리액트에서 Ref를 다루는 또 다른 방법으로, 함수를 사용하여 컴포넌트의 특정 DOM 요소에 대한 참조를 얻는다. 이 방식은 리액트의 생명 주기와 연동되어, 특정 작업을 더욱 세밀하게 제어할 수 있다.
callback Ref는 함수형 컴포넌트 뿐만 아니라 클래스 컴포넌트에서도 사용할 수 있다. 아래 예시처럼 ref
속성에 함수를 전달하여 사용한다.
function MyComponent() {
const myInputRef = useCallback(node => {
if (node !== null) {
node.focus();
}
}, []);
return <input ref={myInputRef} />;
}
위 예제에서 useCallback
을 사용하여 Ref 함수를 만들고, input
요소의 ref
속성에 할당한다. 이 함수는 컴포넌트가 마운트되거나 언마운트될 때 호출되며, 인자로 해당 DOM 요소 또는 null
을 받는다.
이 방식은 더 많은 제어를 원할 때 유용하다. 예를 들어, 컴포넌트가 언마운트될 때 특정 작업을 수행해야 한다면 callback Ref가 적합하다.
callback Ref의 장점 중 하나는 Ref 객체를 직접 다루지 않아도 된다는 것이다. 이는 코드의 간결성과 유지보수의 편리성을 증가시킨다.
또한, callback Ref는 특정 조건이 충족될 때만 Ref를 설정하고 싶을 때도 유용하다. 함수 내에서 로직을 추가하면, 특정 조건에 따라 Ref를 설정하거나 무시할 수 있다.
callback Ref는 리액트의 Ref 시스템 중 매우 유연한 부분이며, 특별한 상황에서 Ref를 다룰 필요가 있을 때 효과적인 해결책을 제공한다.
Ref는 리액트에서 DOM 엘리먼트나 컴포넌트 인스턴스에 직접 접근할 수 있는 매우 유용한 기능이다. 다양한 사용 방법과 케이스에 따라 선택할 수 있는 ref 유형이 있으므로, 상황에 맞게 적절한 방법을 선택하면 된다.