728x90

React에서 useImperativeHandle()은 부모 컴포넌트가 자식 컴포넌트의 메서드나 프로퍼티를 직접적으로 접근할 수 있게 해줍니다. 이를 통해 자식 컴포넌트의 특정 기능에 대한 제어를 부모 컴포넌트에서 수행할 수 있습니다.

useImperativeHandle()은 useRef()와 함께 사용됩니다. useRef()를 사용하여 자식 컴포넌트의 인스턴스를 생성하고, useImperativeHandle()을 사용하여 부모 컴포넌트가 접근 가능한 메서드나 프로퍼티를 반환합니다.

예를 들어, 다음과 같은 자식 컴포넌트가 있다고 가정해 봅시다.

import { forwardRef, useImperativeHandle, useState } from "react";

const ChildComponent = forwardRef((props, ref) => {
  const [count, setCount] = useState(0);

  const incrementCount = () => {
    setCount(count + 1);
  };

  useImperativeHandle(ref, () => ({
    increment: incrementCount,
    count
  }));

  return <div>{count}</div>;
});

export default ChildComponent;

useImperativeHandle()은 ref와 함께 사용되며, ref는 자식 컴포넌트의 인스턴스를 가리킵니다. useImperativeHandle()의 첫 번째 매개변수로는 ref가 전달되며, 두 번째 매개변수로는 부모 컴포넌트에서 접근 가능한 메서드나 프로퍼티를 반환하는 함수가 전달됩니다.

위의 코드에서는 incrementCount() 메서드와 count 프로퍼티를 반환하고 있습니다. 부모 컴포넌트에서는 ref.current.increment()를 호출하여 자식 컴포넌트의 incrementCount() 메서드를 실행할 수 있습니다. 또한, ref.current.count를 통해 자식 컴포넌트의 count 프로퍼티 값을 가져올 수도 있습니다.

부모 컴포넌트에서는 다음과 같이 자식 컴포넌트의 메서드를 호출할 수 있습니다.

import { useRef } from "react";
import ChildComponent from "./ChildComponent";

function ParentComponent() {
  const childRef = useRef(null);

  const handleClick = () => {
    childRef.current.increment();
  };

  return (
    <div>
      <ChildComponent ref={childRef} />
      <button onClick={handleClick}>Increment Child Count</button>
    </div>
  );
}

export default ParentComponent;

위의 코드에서는 ChildComponent를 부모 컴포넌트에서 사용하고 있으며, useRef()를 사용하여 childRef를 생성합니다. 이후, childRef.current.increment()을 호출하여 자식 컴포넌트의 incrementCount() 메서드를 실행하게 됩니다. 이를 통해 자식 컴포넌트의 count 값을 증가시킬 수 있습니다.

useImperativeHandle()은 부모 컴포넌트에서 자식 컴포넌트를 제어해야 하는 경우에 유용합니다. 하지만 이를 남용하면 컴포넌트 간의 결합도가 높아질 수 있으므로 주의해야 합니다.

React 18에서는 useImperativeHandle()에 대한 문법적 변경이 없습니다. 다만, React 18에서는 Concurrent Mode가 기본적으로 활성화되며, 이를 활용하여 컴포넌트의 성능을 개선할 수 있습니다. Concurrent Mode를 활성화하면 useImperativeHandle()을 사용할 때, 부모 컴포넌트가 자식 컴포넌트의 메서드를 호출할 때 발생할 수 있는 성능 문제를 해결할 수 있습니다.

아래는 React 18에서 Concurrent Mode를 사용하는 예시입니다.

import { forwardRef, useImperativeHandle, useState } from "react";

const ChildComponent = forwardRef((props, ref) => {
  const [count, setCount] = useState(0);

  const incrementCount = () => {
    setCount(count + 1);
  };

  useImperativeHandle(ref, () => ({
    increment: incrementCount,
    count
  }));

  return <div>{count}</div>;
});

export default ChildComponent;
import { useRef } from "react";
import ChildComponent from "./ChildComponent";

function ParentComponent() {
  const childRef = useRef(null);

  const handleClick = () => {
    setTimeout(() => {
      childRef.current.increment();
    }, 0);
  };

  return (
    <div>
      <ChildComponent ref={childRef} />
      <button onClick={handleClick}>Increment Child Count</button>
    </div>
  );
}

export default ParentComponent;

위의 코드에서는 handleClick() 함수에서 setTimeout()을 사용하여 childRef.current.increment()을 비동기적으로 호출하고 있습니다. 이를 통해 Concurrent Mode를 활용하여 성능을 개선할 수 있습니다.


내저장소 바로가기 luxury515

'Front-end > React.js' 카테고리의 다른 글

React Hook : useDebugValue()  (0) 2023.04.15
React Hook : useLayoutEffect()  (0) 2023.04.15
React Hook : useRef()  (0) 2023.04.15
React Hook : useMemo()  (0) 2023.04.15
React Hook : useCallback()  (0) 2023.04.15

+ Recent posts