Roen의 iOS 개발로그

React 기초2 : props와 children

by Steady On

📣 이 자료는 Udemy의 React 완벽 가이드 강의와 React 공식문서를 참고하여 작성되었습니다.

그리고 개인적으로 공부하고 이해한 내용을 바탕으로 정리하는 용도로 작성되었으므로 이해를 돕기위한 예시는 최소화하였습니다.

 

props

부모 컴포넌트로부터 자식 컴포넌트로 전달된 데이터! 읽기 전용이므로 어떤 방식으로든 수정해서는 안된다. (수정이 필요한 경우에는 state를 사용!)
부모 컴포넌트에서 <컴포넌트이름 key={데이터이름}/> 이렇게 전달하면, 자식 컴포넌트에서는 매개변수에 props를 넣어 가져오거나 매개변수의 자리에 {데이터이름}을 넣어 받아쓸 수 있다. 전달할 객체가 여러개라면, key={데이터이름}, key2={데이터이름}, key3={데이터이름}로 전달하고, props.원하는키로 해서 필요한 데이터만 골라 쓰는 것도 가능하다.

 

컴포지션(props.children)

: 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 메서드를 호출하는 기법

 

리액트의 컴포넌트 중에는 동일한 스타일 태그의 반복 작성을 피하기 위해서 그런 태그를 모아다가 테두리가 되는 컴포넌트(보통 Card라고 많이 부른다고 한다)를 정의한다. 어차피 대부분의 컴포넌트가 <div>로 쌓인 엘리먼트들의 덩어리를 리턴하기 때문에, 그 <div>태그를 대신한다. 

// div태그 대신 Card 컴포넌트로 감싸진 컴포넌트
const Expenses = (props) => {  
    return (
        <Card className='expenses'> 
            {props.items.map((item) => {
                return <ExpenseItem title={item.title} amount={item.amount} date = {item.date}/>
            })}
        </Card>
    )
}

그럼 이 card 컴포넌트는 어떻게 만들면 될까? 단계별로 하나하나 짚어가며 이해해보자.

// Card 컴포넌트 만들기 1단계
const Card = (props) => <div className="card"></div>

먼저, 대부분의 컴포넌트가 <div>태그로 감싸진다고 했으니까, Card 컴포넌트를 <div> 태그로 정의하고, card라는 클래스에 공통된 스타일 태그를 정의한다. 하지만, 이 컴포넌트를 단순히 이렇게 정의하고 다른 컴포넌트를 감싸는 것 만으로는 의도한대로 다른 요소들이 태그안에 들어가지 않는다. 그때 필요한 것이 props.children이다.

// card 컴포넌트 만들기 2단계
const Card = (props) => <div className="card">{props.children}</div>

이렇게 태그 안에 들어갈 요소를 props.children으로 전달해준다. 이때, 부모 컴포넌트에서 props를 card 컴포넌트에 전달해주지 않아도 children이라는 키워드를 사용하면 알아서 열림/닫힘 태그 사이에 들어오는 요소들을 가져온다. 하지만, 여전히 문제가 있다. className이 card로 고정되어 버려서 공통되지 않은 다른 css가 적용될 수가 없다. 그래서 사용할 className을 props로 전달해주고, 받아온 자식태그들의 className과 함께 쓸 수 있도록 변수를 하나 선언해서 합쳐질 수 있도록 해준다.

// Card 컴포넌트 만들기 3단계
// 부모 컴포넌트에서 props를 보내는 예시
// className을 key로해서 'expenses'라는 이름을 전달!
const Expenses = (props) => {  
    return (
        <Card className='expenses'>
            {props.items.map((item) => {
                return <ExpenseItem title={item.title} amount={item.amount} date = {item.date}/>
            })}
        </Card>
    )
}

// 자식 컴포넌트인 Card에서 받아온 className을 적용하는 방법
// 변수를 선언하고, 최종적으로 'card expenses'가 되도록 함!
const Card = (props) => {
    const classes = 'card ' + props.className

    return (
        <div className={classes}>{props.children}</div>
    )
}

 

 

블로그의 정보

Roen의 iOS 개발로그

Steady On

활동하기