한국어

React Refs를 심층적으로 탐구하고 useRef와 createRef에 초점을 맞춘 종합 가이드입니다. 전역 애플리케이션에서 효율적인 컴포넌트 관리 및 DOM 접근을 위해 각각을 언제, 어떻게 사용해야 하는지 알아보세요.

React Refs: useRef vs. createRef 심층 분석

React 개발의 역동적인 세계에서 컴포넌트 상태를 효율적으로 관리하고 문서 객체 모델(DOM)과 상호작용하는 것은 매우 중요합니다. React Refs는 DOM 요소나 React 컴포넌트에 직접 접근하고 조작할 수 있는 메커니즘을 제공합니다. Ref를 생성하는 두 가지 주요 방법은 useRefcreateRef입니다. 둘 다 Ref를 생성하는 목적은 같지만, 구현 방식과 사용 사례에서 차이가 있습니다. 이 가이드는 이 두 가지 접근 방식을 명확히 설명하고, 특히 전역 사용자를 대상으로 개발할 때 React 프로젝트에서 각각을 언제, 어떻게 효과적으로 활용할 수 있는지에 대한 명확성을 제공하는 것을 목표로 합니다.

React Refs 이해하기

Ref(참조의 약어)는 DOM 노드 또는 React 컴포넌트에 직접 접근할 수 있도록 해주는 React 기능입니다. 이는 다음과 같은 경우에 특히 유용합니다:

React는 UI가 상태와 props를 통해 관리되는 선언적 접근 방식을 권장하지만, 직접적인 조작이 필요한 상황도 있습니다. Refs는 React의 선언적 특성과 명령형 DOM 작업 사이의 간극을 메울 수 있는 방법을 제공합니다.

createRef: 클래스 컴포넌트 접근 방식

createRef는 React에서 제공하는 메서드입니다. 주로 클래스 컴포넌트 내에서 Ref를 생성하는 데 사용됩니다. 클래스 컴포넌트가 인스턴스화될 때마다 createRef는 새로운 Ref 객체를 생성합니다. 이는 컴포넌트의 각 인스턴스가 고유한 Ref를 갖도록 보장합니다.

구문 및 사용법

createRef를 사용하려면 먼저 클래스 컴포넌트, 일반적으로 생성자에서 Ref를 선언합니다. 그런 다음 ref 속성을 사용하여 Ref를 DOM 요소 또는 컴포넌트에 연결합니다.


class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  componentDidMount() {
    // 컴포넌트가 마운트된 후 DOM 요소에 접근
    this.myRef.current.focus();
  }

  render() {
    return ;
  }
}

이 예시에서 this.myRefReact.createRef()를 사용하여 생성됩니다. 그런 다음 input 요소의 ref 속성에 할당됩니다. 컴포넌트가 마운트된 후(componentDidMount에서) this.myRef.current를 사용하여 실제 DOM 노드에 접근하고 작업을 수행할 수 있습니다(이 경우 input에 포커스).

예시: 입력 필드에 포커스하기

컴포넌트가 마운트될 때 입력 필드에 자동으로 포커스를 맞추고 싶은 시나리오를 생각해 봅시다. 이는 Ref의 일반적인 사용 사례이며, 특히 양식이나 대화형 요소에서 그렇습니다.


class FocusInput extends React.Component {
  constructor(props) {
    super(props);
    this.inputRef = React.createRef();
  }

  componentDidMount() {
    this.inputRef.current.focus();
  }

  render() {
    return (
      
); } }

이 예시에서 FocusInput은 마운트된 직후 입력 필드에 포커스를 맞춥니다. 이는 컴포넌트가 렌더링되자마자 사용자의 주의를 입력 요소로 유도하여 사용자 경험을 개선할 수 있습니다.

Important Considerations with createRef

useRef: 함수형 컴포넌트 Hook

useRef는 React 16.8에서 도입된 Hook입니다. 함수형 컴포넌트 내에서 변경 가능한 Ref 객체를 생성하는 방법을 제공합니다. createRef와 달리 useRef는 컴포넌트가 렌더링될 때마다 동일한 Ref 객체를 반환합니다. 이로 인해 리렌더링을 유발하지 않고 렌더링 전반에 걸쳐 값을 유지하는 데 이상적입니다.

구문 및 사용법

useRef를 사용하는 것은 간단합니다. 초기 값을 전달하여 useRef Hook을 호출합니다. Hook은 .current 속성을 가진 객체를 반환하며, 이를 사용하여 값에 접근하고 수정할 수 있습니다.


import React, { useRef, useEffect } from 'react';

function MyFunctionalComponent() {
  const myRef = useRef(null);

  useEffect(() => {
    // 컴포넌트가 마운트된 후 DOM 요소에 접근
    if (myRef.current) {
      myRef.current.focus();
    }
  }, []);

  return ;
}

이 예시에서 useRef(null)은 초기 값이 null인 Ref를 생성합니다. useEffect Hook은 컴포넌트가 마운트된 후 DOM 요소에 접근하는 데 사용됩니다. myRef.current 속성은 input 요소에 대한 참조를 보유하여 포커스를 맞출 수 있도록 합니다.

예시: 이전 prop 값 추적하기

useRef의 강력한 사용 사례 중 하나는 prop의 이전 값을 추적하는 것입니다. Ref 변경은 리렌더링을 유발하지 않으므로, UI에 영향을 미치지 않고 렌더링 전반에 걸쳐 유지하려는 값을 저장하는 데 사용할 수 있습니다.


import React, { useRef, useEffect } from 'react';

function PreviousValueComponent({ value }) {
  const previousValue = useRef();

  useEffect(() => {
    previousValue.current = value;
  }, [value]);

  return (
    

Current Value: {value}

Previous Value: {previousValue.current}

); }

이 예시에서 previousValue.currentvalue prop의 이전 값을 저장합니다. useEffect Hook은 value prop이 변경될 때마다 Ref를 업데이트합니다. 이를 통해 현재 값과 이전 값을 비교할 수 있으며, 이는 변경 사항을 감지하거나 애니메이션을 구현하는 데 유용할 수 있습니다.

Important Considerations with useRef

useRef vs. createRef: 상세 비교

이제 useRefcreateRef를 각각 살펴보았으므로, 주요 차이점과 언제 어떤 것을 선택해야 하는지를 강조하기 위해 나란히 비교해 보겠습니다.

기능 useRef createRef
컴포넌트 유형 함수형 컴포넌트 클래스 컴포넌트
Hook 또는 메서드 Hook 메서드
Ref 인스턴스 모든 렌더링에서 동일한 Ref 객체 반환 컴포넌트의 각 인스턴스에서 새로운 Ref 객체 생성
사용 사례
  • DOM 요소 접근
  • 리렌더링을 유발하지 않고 렌더링 전반에 걸쳐 값 유지
  • 이전 prop 값 추적
  • 리렌더링을 유발하지 않는 변경 가능한 값 저장
  • DOM 요소 접근
  • 자식 컴포넌트 메서드 접근

올바른 Ref 선택하기: 결정 가이드

useRefcreateRef 중에서 선택하는 데 도움이 되는 간단한 가이드입니다:

DOM 조작을 넘어: Ref의 고급 사용 사례

DOM 요소에 접근하고 조작하는 것이 Ref의 주요 사용 사례이지만, 이러한 핵심 기능 이상으로 다양한 가능성을 제공합니다. Ref가 특히 유용할 수 있는 몇 가지 고급 시나리오를 살펴보겠습니다.

1. 자식 컴포넌트 메서드 접근

Ref는 자식 컴포넌트에 정의된 메서드에 접근하는 데 사용될 수 있습니다. 이를 통해 부모 컴포넌트가 자식으로부터 직접 작업을 트리거하거나 데이터를 검색할 수 있습니다. 이 접근 방식은 자식 컴포넌트에 대한 세밀한 제어가 필요할 때 특히 유용합니다.


class ParentComponent extends React.Component {
  constructor(props) {
    super(props);
    this.childRef = React.createRef();
  }

  handleClick = () => {
    // 자식 컴포넌트의 메서드 호출
    this.childRef.current.doSomething();
  };

  render() {
    return (
      
); } } class ChildComponent extends React.Component { doSomething = () => { console.log('자식 컴포넌트 액션이 트리거되었습니다!'); }; render() { return
이것은 자식 컴포넌트입니다.
; } }

이 예시에서 ParentComponent는 Ref를 사용하여 ChildComponent에 접근하고 doSomething 메서드를 호출합니다.

2. 포커스 및 선택 관리

Ref는 입력 필드 및 기타 대화형 요소 내에서 포커스와 선택을 관리하는 데 매우 유용합니다. 이는 접근성 높고 사용자 친화적인 인터페이스를 만드는 데 중요합니다.


import React, { useRef, useEffect } from 'react';

function FocusOnMount() {
  const inputRef = useRef(null);

  useEffect(() => {
    if (inputRef.current) {
      inputRef.current.focus();
      inputRef.current.select(); // 입력 필드의 텍스트 선택
    }
  }, []);

  return ;
}

이 예시는 컴포넌트가 마운트되자마자 입력 필드에 포커스를 맞추고 텍스트를 선택합니다.

3. 요소 애니메이션

Ref는 애니메이션 라이브러리(예: GreenSock 또는 Framer Motion)와 함께 사용하여 DOM을 직접 조작하고 복잡한 애니메이션을 만들 수 있습니다. 이를 통해 애니메이션 시퀀스를 세밀하게 제어할 수 있습니다.

단순화를 위한 일반 JavaScript 예시:


import React, { useRef, useEffect } from 'react';

function AnimatedBox() {
  const boxRef = useRef(null);

  useEffect(() => {
    const box = boxRef.current;
    if (box) {
      // 간단한 애니메이션: 상자를 오른쪽으로 이동
      box.animate(
        [
          { transform: 'translateX(0)' },
          { transform: 'translateX(100px)' },
        ],
        {
          duration: 1000, // 1초
          iterations: Infinity, // 무한 반복
          direction: 'alternate',
        }
      );
    }
  }, []);

  return 
; }

이 예시는 웹 애니메이션 API를 사용하여 간단한 상자를 수평으로 앞뒤로 움직이는 애니메이션을 만듭니다.

전역 애플리케이션에서 React Refs 사용을 위한 모범 사례

전역 사용자를 대상으로 React 애플리케이션을 개발할 때, Ref가 국제화(i18n) 및 지역화(l10n)와 어떻게 상호작용하는지 고려하는 것이 중요합니다. 다음은 몇 가지 모범 사례입니다:

1. 접근성 (A11y)

Ref 사용이 접근성에 부정적인 영향을 미치지 않도록 하십시오. 예를 들어, 프로그래밍 방식으로 요소에 포커스를 맞출 때 사용자의 포커스 순서와 포커스 변경이 스크린 리더 및 키보드 사용자에게 적절한지 고려하십시오.


import React, { useRef, useEffect } from 'react';

function AccessibleFocus() {
  const buttonRef = useRef(null);

  useEffect(() => {
    const button = buttonRef.current;
    if (button) {
      // 버튼이 사용자에게 이미 포커스되어 있지 않은 경우에만 포커스
      if (document.activeElement !== button) {
        button.focus();
      }
    }
  }, []);

  return ;
}

2. 국제화된 입력 필드

입력 필드로 작업할 때, 다른 언어에서 사용되는 다양한 입력 방식과 문자 세트에 유의하십시오. Ref 기반 조작(예: 선택, 커서 위치)이 다양한 입력 유형과 로케일에서 올바르게 작동하는지 확인하십시오. 다른 언어와 입력 방식으로 컴포넌트를 철저히 테스트하십시오.

3. 오른쪽에서 왼쪽(RTL) 레이아웃

애플리케이션이 RTL 언어(예: 아랍어, 히브리어)를 지원하는 경우, Ref를 사용하는 DOM 조작이 반전된 레이아웃을 고려하는지 확인하십시오. 예를 들어, 요소를 애니메이션할 때 RTL 언어의 애니메이션 방향을 반전시키는 것을 고려하십시오.

4. 성능 고려 사항

Ref는 DOM과 상호작용하는 강력한 방법을 제공하지만, 과도하게 사용하면 성능 문제를 일으킬 수 있습니다. 직접적인 DOM 조작은 React의 가상 DOM 및 재조정 프로세스를 우회하여 불일치 및 느린 업데이트로 이어질 수 있습니다. Ref는 신중하게 그리고 필요할 때만 사용하십시오.

결론

React Refs, 특히 useRefcreateRef는 React 개발자에게 필수적인 도구입니다. 각 접근 방식의 뉘앙스를 이해하고 언제 효과적으로 적용해야 하는지 아는 것은 견고하고 성능 좋은 애플리케이션을 구축하는 데 중요합니다. createRef는 클래스 컴포넌트 내에서 Ref를 관리하는 표준으로 남아 있으며, 각 인스턴스가 고유한 Ref를 갖도록 보장합니다. 렌더링 전반에 걸쳐 지속되는 특성을 가진 useRef는 함수형 컴포넌트에 이상적이며, DOM 요소를 관리하고 불필요한 리렌더링을 유발하지 않고 값을 유지하는 방법을 제공합니다. 이러한 도구를 현명하게 활용함으로써, 접근성 높고 성능 좋은 인터페이스로 전 세계 사용자를 만족시키는 React 애플리케이션의 기능과 사용자 경험을 향상시킬 수 있습니다.

React가 계속 발전함에 따라, 이러한 기본 개념을 숙달하면 지리적, 문화적 경계를 초월하는 혁신적이고 사용자 친화적인 웹 경험을 만들 수 있습니다. 진정으로 전 세계적인 애플리케이션을 제공하기 위해 접근성, 국제화 및 성능을 우선시하는 것을 기억하십시오.