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 |