ABOUT ME

-

  • [ React ] ForwardRef + useImperativeHandler 자식 컴포넌트 함수 사용하기
    Front/React 2025. 12. 10. 14:19
    반응형

    현재 react-data-grid를 활용하여 그리드를 만들어 보고 있어서

    이때 그리드의 행,열 추가 및 삭제 기능을 자식컴포넌트에서 다루는게 편하것같아서

     

    부모쪽에서는 그냥 자식컴포넌트의 함수만 호출 하도록 처리하기 위해

    forwardRef와 useImperativeHandle을 사용


    ForwardRef

    더보기

    ref 연결한 대상의 인스턴스나 객체를 ref.current에 연결시켜주는 역할을 한다.

     

    DOM이면 DOM 객체 연결

    클래스 컴포넌트면 컴포넌트 인스턴스 연결

    export default forwardRef(function MetaGrid(props: Props, ref: React.Ref<MetaGridRef>) {
    	return (
        )
    }

     

    props는 함수형 컴포넌트에서 전달할 파라미터 타입이고,

     

    forwardRef를 사용했기때문에 두번째 인자로 ref를 전달한다.

    그러면 forwardRef는 부모가 자식에게 전달된 ref를 자식 내부에서 받을 수 있도록 해준다.

    <MetaGrid
      ref={metaGridRef}
    />

     

    이런식으로 활용하면 이제 ref가 자식과 부모의 통로 역할 을 해준다.


    useImperativeHandle

    그럼 ref를 부모와 자식간의 연결을 해주었으니

    이제 자식의 어디랑 연결을 해줄지 정해야한다.

     

    자식의 함수에 접근할 수 있도록 해야하므로

    useImperativeHandle을 사용하여 직접 만든 객체에 접근 할 수 있도록 한다.

     

    useImperativeHandle을 사용한 이유는 부모쪽에서 자식의 특정 함수들 혹은 값에만 접근 할 수 있도록 하기 위해서 사

     

    그리드 컴포넌트에서 행,열추가 및 수정된 데이터를 가져오는 함수를 만들어 부모쪽에서 접근 할 수 있도록 처리

      useImperativeHandle(ref,() => ({
            addRow,
            deleteRow,
            addColumn,
            deleteColumn,
            getSaveData,
        }))

    Useage

    이제 부모 컴포넌트에서 ref를 연결하고 버튼 클릭시에 ref.current.(함수명) 실행을 해주면 된다.

                        <button onClick={deleteRow} className="btn-white">
                            - 행 삭제
                        </button>
                        <button onClick={deleteColumn} className="btn-white">
                            - 열 삭제
                        </button>
                        <button onClick={addRow} className="btn-white">
                            + 행 추가
                        </button>
                        <button onClick={addColumn} className="btn-white">
                            + 열 추가
                        </button>
                        <MetaGrid
                          ref={metaGridRef}
                        />
        const addRow = () => {
            metaGridRef.current?.addRow()
        };
    
        const addColumn = () => {
            metaGridRef.current?.addColumn()
        };
    
        const deleteRow = () => {
            metaGridRef.current?.deleteRow()
        }
    
        const deleteColumn = () => {
            metaGridRef.current?.deleteColumn()
        };

     

    자식컴포넌트에서는 테스트를 위해 console만 찍어서 테스트 확인

        /* row 추가 */
        const addRow = () => {
            console.log('addRow')
        };
    
        /* row 삭제 */
        const deleteRow = () => {
            console.log('deleteRow')
        }
    
        /* column 추가*/
        const addColumn = () => {
            console.log('addColumn')
        };
    
        /* column 삭제 */
        const deleteColumn = () => {
            console.log('deleteColumn')
        };

     

    그러면 그리드 컴포넌트에서 console이 찍히는 것을 확인 할 수 있다.

    728x90
    반응형