children에게 Props 전달하기

Jiwon·2024년 2월 8일
0

여러 곳에서 사용하는 공통된 컴포넌트의 모든 자식 요소에 props를 전달하고 싶었다.

export const CommonComponent = () => {
   const [state, dispatch] = useReducer(reducer, {
    status: status || 'enable',
  });
	return (
      <div>
      	{children} // status를 children에게 모두 전달하고 싶다!
      </div>
    )
}
function reducer(state: any, action: any) {
  switch (action) {
    case 'mouse_enter':
      return {
        ...state,
        status: 'hover',
      };

    case 'mouse_leave':
      return {
        ...state,
        status: 'enable',
      };
  }

  return state;
}

굳이 Provider를 만들고 싶지 않았는데, 찾다가 새로운 걸 발견했다.

https://react.dev/reference/react/cloneElement#cloneelement

cloneElement를 이용해서 아래와 같이 전달하고 싶은 props를 지정할 수 있었다.

export const CommonComponent = () => {
   const [state, dispatch] = useReducer(reducer, {
    status: status || 'enable',
  });
	return (
      <div>
      {cloneElement(children, { status: state.status })}
      </div>
    )
}
function reducer(state: any, action: any) {
  switch (action) {
    case 'mouse_enter':
      return {
        ...state,
        status: 'hover',
      };

    case 'mouse_leave':
      return {
        ...state,
        status: 'enable',
      };
  }

  return state;
}

하지만 기본적으로 cloneElement는 추천되지는 않는다.
왜냐하면, props가 전달되고 있는지 상위 컴포넌트에서는 코드만 보고 알 수 없기 때문이다.
따라서, 좋은 코드가 아니다.
이러한 대안을 이용해서 아래처럼 다시 수정해보았다.

interface Props {
  status: 'enable' | 'active' | 'hover';
  children: (status: 'enable' | 'active' | 'hover') => JSX.Element;
}
export const CommonComponent = ({ status, icon }: Props) => {
   const [state, dispatch] = useReducer(reducer, {
    status: status || 'enable',
  });
	return (
      <div>
      	{children(state.status)}
      </div>
    )
}
function reducer(state: any, action: any) {
  switch (action) {
    case 'mouse_enter':
      return {
        ...state,
        status: 'hover',
      };

    case 'mouse_leave':
      return {
        ...state,
        status: 'enable',
      };
  }

  return state;
}

profile
hi there~!

0개의 댓글