61일차(1)[forwardRef]

진하의 메모장·2025년 4월 3일
1

공부일기

목록 보기
63/66
post-thumbnail

2025 / 04 / 03

오늘 수업 시간에는 부모 컴포넌트가 자식의 특정 요소를 접근할 수 있게 하는 방법을 배웠습니다. 사실 이거 어떤식으로 동작하는거고 왜 써야하는건지.. 잘모르겠습니다..ㅎㅎ 벨로그에 천천히 정리하면서 한 번 더 공부하는 시간을 갖도록 하겠습니다.



💌 dialog 태그

  • 웹에서 대화형 모달 창을 만들 때 사용하는 HTML 태그입니다.
  • 페이지 내에서 모달처럼 나타나거나, 대화 상자를 보여주는 용도로 사용됩니다.
  • <div>, popup으로 만들 때보다 간단하고 효율적으로 모달을 구현할 수 있습니다.


1. 사용 방법

  • <dialog> 태그는 기본적으로 HTML5에서 도입되었습니다.
<dialog open>
   <h2>모달 내용</h2>
   <p>여기에 모달 창 내용을 넣습니다.</p>
   <button>닫기</button>
</dialog>

open 속성

  • 이 속성을 지정하면 모달이 화면에 표시됩니다.
  • 속성이 없으면 기본적으로 모달은 숨겨져 있습니다.

close( ), showModal( )

  • close( )는 모달을 닫고, showModal( )은 모달을 화면에 표시합니다.


2. 작동 원리

1. dialog 태그

  • 기본적으로 display: none으로 숨겨져 있습니다.
  • open 속성을 설정하면 display: block으로 변경됩니다.

2. showModal( ) 메서드

  • dialog 요소를 모달로 띄우며, 배경을 비활성화합니다.
  • 사용자가 모달을 닫을 때까지 다른 상호작용을 막을 수 있습니다.

3. close( ) 메서드

  • 모달을 닫고, 다시 보이지 않게 만듭니다.


💌 forwardRef

  • 부모 컴포넌트가 자식 컴포넌트 내부의 DOM 요소나 함수에 접근할 수 있게 하는 기능입니다.
  • React에서는 일반적으로 ref를 사용하여 DOM을 참조할 수 있지만, forwardRef를 사용하면 자식 컴포넌트의 DOM에 직접 접근할 수 있게 됩니다.


1. 사용 방법

  • forwardRef는 컴포넌트를 감싸고, 내부에서 ref를 전달할 수 있도록 해줍니다.
  • 그 후 부모 컴포넌트에서 ref를 사용해 해당 DOM 요소에 접근할 수 있습니다.
import React, { forwardRef } from 'react';

const MyComponent = forwardRef((props, ref) => {
  return <div ref={ref}>Hello, World!</div>;
});

export default MyComponent;


2. 특징 & 장점

특징

  • forwardRef는 컴포넌트 내부에서 ref를 자식 컴포넌트에 전달할 수 있게 해줍니다.
  • ref는 컴포넌트가 아닌 DOM 요소를 참조하는 데 사용됩니다.

장점

  • 부모 컴포넌트는 자식 컴포넌트의 DOM 요소나 메서드에 직접 접근할 수 있게 되어, 여러 UI 요소를 동적으로 제어하는 데 유용합니다.


3. 주의할 점

  • forwardRef는 보통 함수형 컴포넌트에서만 사용됩니다.
  • forwardRef를 사용할 때, 내부에서 ref를 꼭 전달해야 합니다.


4. 사용 예시

ParentComponent.jsx

import React, { useRef } from "react";
import ChildComponent from "./ChildComponent"; // ChildComponent를 import

const ParentComponent = () => {
  // useRef로 input 요소의 ref를 생성
  const inputRef = useRef();

  // input 요소에 포커스를 주는 함수
  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      {/* ChildComponent에 ref를 전달 */}
      <ChildComponent ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
};

export default ParentComponent;
  • useRef로 inputRef를 생성하고, 이를 ChildComponent에 ref로 전달합니다.
  • 버튼 클릭 시 focusInput 함수가 실행됩니다.
  • inputRef.current.focus( )로 input 요소에 포커스를 줍니다.

ChildComponent.jsx

import React, { forwardRef } from "react";

// forwardRef를 사용하여 부모로부터 전달받은 ref를 input 요소에 연결
const ChildComponent = forwardRef((props, ref) => {
  return <input ref={ref} />;
});

export default ChildComponent;
  • forwardRef를 사용하여 부모 컴포넌트에서 ref를 전달받고, input 요소에 연결합니다.
  • forwardRef를 사용하면 부모 컴포넌트가 자식의 DOM 요소를 참조할 수 있습니다.


💌 전체 정리

  • 지금까지 배운 Ref와 forwardRef부분에서 헷갈리는 부분을 정리해보도록 하겠습니다.


1. ref란 무엇인가?

  • DOM 요소나 자식 컴포넌트의 인스턴스를 참조하기 위해 사용하는 객체입니다.
  • 컴포넌트 외부에서도 DOM 요소, 컴포넌트 속성이나 메서드에 접근할 수 있습니다.
  • 리액트는 기본적으로 선언형 UI를 사용하여 컴포넌트의 상태에 따라 화면을 렌더링하지만, UI 요소에 직접 접근하거나 조작할 필요가 있을 때 ref를 사용합니다.
import { useRef } from "react";

function MyComponent() {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus(); // input 요소에 포커스를 줌
  };

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={focusInput}>Focus the input</button>
    </div>
  );
}

export default MyComponent;
  • inputRef는 input 요소를 참조하게 됩니다.
  • input 요소의 메서드인 focus( )를 호출할 수 있습니다.


2. forwardRef의 필요성

  • 기본적으로 ref는 자식의 DOM에 접근할 수 없습니다.
  • 리액트에서는 부모 컴포넌트가 자식 컴포넌트의 내부 요소에 접근하는 것을 막습니다.
  • 부모가 자식 컴포넌트의 DOM 요소나 내부 메서드에 접근해야 할 때가 있습니다.
  • ex) 포커스를 주거나, 스크롤을 조정하거나, 애니메이션 효과를 적용할 때
  • forwardRef를 사용하여 부모가 자식 컴포넌트의 DOM에 접근할 수 있도록 만들어줍니다.


3. forwardRef 사용 예시

1. forwardRef를 사용하지 않은 경우

  • forwardRef를 사용하지 않으면 부모는 자식의 DOM에 직접 접근할 수 없습니다.

ParentComponent.jsx

function ParentComponent() {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus();  // 오류가 발생함
  	// 자식 컴포넌트에는 ref를 직접 전달할 수 없음
  };

  return (
    <div>
      <ChildComponent ref={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

export default ParentComponent;

ChildComponent.jsx

function ChildComponent() {
  return <input type="text" />;
}
  • 이 코드에서 ref를 자식 컴포넌트에 전달하려고 하면 오류가 발생합니다.
  • ChildComponent는 함수형 컴포넌트이고, ref가 직접 전달될 수 없기 때문입니다.


2. forwardRef를 사용한 경우

  • forwardRef를 사용하여 부모가 자식의 DOM에 접근할 수 있게 만듭니다.

ParentComponent.jsx

function ParentComponent() {
  const inputRef = useRef();

  const focusInput = () => {
    inputRef.current.focus();  // input 요소에 포커스를 줄 수 있음
  };

  return (
    <div>
      <ChildComponent ref={inputRef} />  {/* forwardRef를 통해 ref 전달 */}
      <button onClick={focusInput}>Focus Input</button>
    </div>
  );
}

export default ParentComponent;

ChildComponent.jsx

// 자식 컴포넌트에서 forwardRef를 사용하여 ref 전달을 가능하게 함
const ChildComponent = forwardRef((props, ref) => {
  return <input type="text" ref={ref} />;
});
  • 부모 컴포넌트에서 ref={inputRef}를 자식 컴포넌트에 전달할 수 있게 됩니다.
  • ChildComponent는 forwardRef를 통해 부모 컴포넌트의 ref를 자신에게 전달받습니다.
  • 전달 받은 부모 컴포넌트의 ref를 input 요소에 연결합니다.
  • 부모 컴포넌트는 inputRef.current를 통해 자식 컴포넌트의 input 요소에 접근할 수 있습니다.


4. 역할 및 사용 이유

forwardRef의 역할

  • 부모 컴포넌트의 ref를 전달하여 자식 컴포넌트의 DOM 요소나 메서드에 접근할 수 있도록 합니다.
  • 자식 컴포넌트는 ref를 전달받아 그 ref를 원하는 DOM 요소나 메서드에 연결할 수 있습니다.


forwardRef를 사용 이유

1. DOM 요소 접근

  • 부모 컴포넌트가 자식 컴포넌트의 DOM 요소에 접근해야 할 때 사용합니다.

2. 자식 컴포넌트의 메서드 호출

  • 자식 컴포넌트의 내부 메서드를 부모가 호출해야 할 때도 사용됩니다.


5. forwardRef vs useRef

  • useRef는 부모 컴포넌트에서 DOM 요소나 컴포넌트 인스턴스를 참조하기 위한 훅입니다.
  • forwardRef는 자식 컴포넌트로 ref를 전달하는 기능을 담당하는 함수입니다.

useRef

  • 부모에서 ref를 생성합니다.

forwardRef

  • 자식 컴포넌트가 ref를 받을 수 있도록 도와줍니다.


6. 두 번째 인자?

forwardRef는 두 가지 인자를 받습니다.

  • 첫 번째 : props (부모로부터 전달된 데이터)
  • 두 번째 : ref (부모로부터 전달된 ref)
  • ref를 두 번째 인자로 받는 이유는 리액트의 내부 구현 방식에 있습니다.
  • 리액트는 forwardRef로 감싸진 컴포넌트가 ref를 자식의 DOM 요소에 연결할 수 있도록 해야 하기 때문에, ref를 두 번째 인자로 받아 자식 컴포넌트에 전달합니다.
  • 리액트는 props와 ref를 구분하기 위해 ref를 두 번째 인자로 받으며, 이렇게 해야 ref가 자식 컴포넌트의 DOM 요소에 제대로 연결될 수 있습니다.



61일차 후기(1)

  • 자식 컴포넌트를 작성할 때 리턴을 적지 않아서 다른 사람은 다 실행되는데 저만 실행이 되지 않아서 당황스러웠습니다. 오류 뜬 이유를 알고나서는 황당.... ╭(๑¯д¯๑)╮
  • 조심하려고 해도 기억이 안나는 것 같습니다.. 한 번씩 틀리다보면 익숙해지겠죠..?
  • 설명을 듣고 실습을 했을 때까지만 해도 forwardRef의 역할과 왜 써야하는지 어려웠는데, 벨로그를 정리하면서 다시 복습하니까 조금 나은 것 같습니다.
  • 오늘 추가로 API 호출해서 블로그를 만드는 과제를 받았는데.. 머리가 아파요. (๑-﹏-๑)
profile
૮꒰ ྀི〃´꒳`〃꒱ა

0개의 댓글