본문 바로가기
react

[react] PropsWithChildren

by dev__log 2024. 7. 11.

요즘 리액트 기초를 다시 공부 중인데, PropsWithChildren 타입을 알게 됐다.

 

이 타입은 상위 컴포넌트에서 하위 컴포넌트로 children을 내려줄 때 타입을 지정하는 children : ReactNode를 대체할 수 있다.

 

마우스 오른쪽 버튼을 눌러서 index.d.ts에 이동하여 type PropsWithChildren 타입을 보면 children을 반드시 설정하지 않아도 되는 선택적인 속성임을 알 수 있다.

index.d.ts 의 일부

 

만약 꼭! children이 들어가야 한다면 이 속성을 사용하는 것은 바람직하지 않을 것 같다. 

꼭 필요한 곳에 children이 들어가지 않았는데도 에러가 나지 않을 것 이기 때문이다.

그래서 선택적으로 children이 필요한 곳에는 PropsWithChildren 타입을 사용하고 무조건 들어가야 한다면 기존대로 사용하는 것이 바람직하겠다.

 

이전에 팀 프로젝트로 모달을 만들었던 코드이다.

import type { ReactNode } from 'react'
import close from '@/../public/images/close-button.svg'
import Image from 'next/image'

type Modal = {
  children: ReactNode
  onClick: () => void
}

const Modal = ({ children, onClick }: Modal) => {
  const modalShadow =
    'shadow-[0px_4px_4px_#00000033,0px_0px_0px_1px_#0000001a,0px_0px_0px_4px_#0000001a,0px_0px_0px_3px_#ffffff33,inset_0px_1px_2px_#ffffff33,inset_0px_-4px_1px_#0000001a]'

  return (
    <div>
      <div className='fixed bottom-0 left-0 right-0 top-0 z-10 bg-black/[0.7]'></div>
      <div
        className={`fixed left-1/2 top-1/2 h-[680px] max-h-[80vh] w-[516px] max-w-[80%] -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-[2rem] border-4 border-[#474747] bg-[#3d3d3d] p-4 ${modalShadow} z-10`}
      >
        <button
          type='button'
          onClick={onClick}
          className='absolute right-[2rem] top-[2rem]'
        >
          <Image src={close} width={24} height={24} alt='닫기 아이콘' />
        </button>
        {children}
      </div>
    </div>
  )
}

export default Modal

 

 

위 코드에서 type Modal의 타입을 보면 children : ReactNode로 지정하였는데, 아래와 같이 변경할 수 있다.

import type { PropsWithChildren } from 'react'

type Modal = {
  // children: ReactNode //변경
  onClick: () => void
}

const Modal = ({ children, onClick }: PropsWithChildren<Modal>) => { //변경
  const modalShadow =
    'shadow-[0px_4px_4px_#00000033,0px_0px_0px_1px_#0000001a,0px_0px_0px_4px_#0000001a,0px_0px_0px_3px_#ffffff33,inset_0px_1px_2px_#ffffff33,inset_0px_-4px_1px_#0000001a]'

  return (
    <div>
      <div className='fixed bottom-0 left-0 right-0 top-0 z-10 bg-black/[0.7]'></div>
      <div
        className={`fixed left-1/2 top-1/2 h-[680px] max-h-[80vh] w-[516px] max-w-[80%] -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-[2rem] border-4 border-[#474747] bg-[#3d3d3d] p-4 ${modalShadow} z-10`}
      >
        <button
          type='button'
          onClick={onClick}
          className='absolute right-[2rem] top-[2rem]'
        >
          <Image src={close} width={24} height={24} alt='닫기 아이콘' />
        </button>
        {children}
      </div>
    </div>
  )
}

export default Modal

 

'react' 카테고리의 다른 글

[react] useCallback  (2) 2024.07.17
[react] 클래스형 컴포넌트  (0) 2024.07.11
react-query useQuery / useMutation  (0) 2024.02.19
axios  (0) 2024.02.16
react-router outlet  (0) 2024.02.07