너와 나의 프로그래밍

React.js - 부모에서 자식 함수 호출하기 본문

Front-End/Next.js & React.js

React.js - 부모에서 자식 함수 호출하기

Whatever App's 2022. 10. 17. 17:51

 

프론트엔드 개발자 기술면접을 보는 중 "부모에서 자식 함수를 호출하는 방법"은 무엇일까요? 라는 질문을 받은 적이 있다.

 

React.js는 Vue.js와 다르게 정말 대표적인 "단방향 통신"의 프론트엔드 라이브러리인데 굳이 왜 자식에서 함수를 호출해야 할까? 라는 의문점이 들었다.

 

하지만 개발을 하다보면 참 여러가지 케이스가 많이 발생하는데 어쩔 수 없이 자식에서 함수를 호출해야되는 상황도 있기 마련이다.

 

대표적인 단방향 통신의 React.js에서 과연 자식 함수를 어떻게 호출할 수 있는거지?라는 의문에 구글링을 해본 결과 정말 방법이 있어서 "아니 이런것이 있었어!?🙄", "이 점은 내가 아직 부족한게 많구나...😭" 라는 점도 느끼게 되었다.

 

그 방법은 React의 useRef, forardRefuseImperativeHandle Hook으로 해결할 수 있다.

세 개의 Hook으로 만든 간단한 예제를 소개해볼까 한다.

 

// Parent.tsx

import React, { useRef } from "react";
import Child from "./components/Child";

const Parent = () => {
  const childRef = useRef<HTMLInputElement | any>(); // any 타입은 지양하지만 일단 예제...

  return (
    <div>
      <button onClick={() => childRef.current?.setText()}>
        자식 컴포넌트 함수 호출 버튼
      </button>
      <Child ref={childRef} />
    </div>
  );
}

export default Parent;
// Child.tsx

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

const Child = forwardRef((props, ref) => {
  const [insertText, setInsertText] = useState("");

  useEffect(() => {
    console.log(ref);
  }, [ref]);

  useImperativeHandle(ref, () => ({
    setText: () => {
      setInsertText("test");
    },
  }));

  return <input type="text" value={insertText} />;
});

export default Child;

위 예제의 간단한 동작 원리를 설명 해보자면

 

1. 부모 컴포넌트에서 useRef로 자식 컴포넌트 Child에 전달.

2. 부모 컴포넌트에서 자식 컴포넌트안 함수 사용을 위해 button Element 삽입, onClick을 통해 자식 컴포넌트 함수 바인딩.

3. 자식 컴포넌트에서 forwardRef로 ref와 props를 받을 수 있도록 구현.

4. input Element를 만들어 setState를 통해 state를 변경할 수 있는 state를 하나 생성.

5. useImperativeHandle Hook에 setText라는 함수 생성 후 setState를 통해 input value값을 update 시키도록 구현.

 

자식 컴포넌트의 useEffect를 통해 forwardRef Hook을 사용한 ref Attribute가 어떻게 넘어오는지 console.log를 통해 확인해 봤다.

 

자식 컴포넌트의 setText

자식 컴포넌트에서 useImperativeHandle Hook안에 생성된 setText라는 함수가 나오는 걸 볼 수 있다.

부모 컴포넌트에서 setText의 함수의 사용이 가능하다.

반응형