내일배움캠프

230629 React.Children 사용해보기

Neda 2023. 6. 29. 20:58

230629 React.Children 사용해보기

기존에 모든 데이터를 props로 받다 보니 명시적으로 밖에서 어떻게 보이는지 어렵다는 생각을 했다. 

보기 불편한 컴포넌트

예를 들어 아래와 같은 Select 컴포넌트를 보면 , 저 속성들이 어떻게 쓰이는지 바로 파악하기는 힘들다. 그래서 아래와 같이 SelectItem을 밖으로 빼서 함께 작성하면 보기 쉽다고 생각하고 찾아보니 이런 식으로 만든 컴포넌트들이 많다는 것을 알게 되었다. 

<Select
  defaultValue={"리액트"}
  values={["react","java","spring","node"]}
  options={["리액트", "자바", "스프링", "노드"]}
  onChange={(value) => alert(value)}
/>
<Select
  name={"리액트 목록"}
  defaultValue={"과목"}
  onChange={(value) => alert(value)}
>
  <SelectItem value={"react"}>리액트</SelectItem>
  <SelectItem value={"java"}>자바</SelectItem>
  <SelectItem value={"spring"}>스프링</SelectItem>
  <SelectItem value={"node"}>노드</SelectItem>
</Select>

 

Children API

위와 같이 SelectItem이라는 컴포넌트의 배열을 children으로 전달하면 {children}으로 받아서 렌더링 해 줄 수 있다.
하지만 SelectItem 각각에 이벤트 리스너를 붙이거나 다른 props를 전달해 주어야 할 경우 난감해진다.

React에서는 이러한 개발자의 고민을 덜어주기 위해서 Children이라는 API를 제공한다.
이 API는 props로 받는 children를 조작하는데 사용한다.

{options.map((item,i) => 
  <SelectItem 
    key={i}
    value={values[i]}
    tabIndex='0' 
    onKeyDown={(e) => handleKeyDownItem(e,i)} 
    onClick={(e) => selectItem(i)}
  >
  {item}
  </SelectItem>
)}
{Children.map(children, (child, i) =>
  <li 
    key={i} 
    tabIndex='0' 
    onKeyDown={(e) => handleKeyDownItem(e,child.props.value)} 
    onClick={(e) => selectItem(child.props.value,child.props.children)}  
  >
  {child}
  </li>
)}

 

여기서 Select 컴포넌트는 html 요소의 select와 option처럼 만들기 위해서 Children을 사용하여 비슷하게 보이도록 구현했지만, 넘겨야 하는 데이터가 배열같이 항상 형식이 같으면서 매우 클 경우에는 props로 넘기는 것이 더 좋을 것 같다.