3. 컴포넌트에 값을 전달할 수 있게 해 주는 props

최건우·2021년 2월 12일
0

react.js

목록 보기
4/6

1. 컴포넌트 만들어 보기에서 우리는 컴포넌트를 만드는 법을 살펴 보았습니다. 컴포넌트를 사용하여 원하는 데이터를 웹 페이지 화면에 그릴 수 있습니다. 그런데, 많은 경우에, 컴포넌트는 개발자에 의해 미리 정해진 데이터를 단순히 그려주는 정도가 아니라, 사용자가 입력하는 값에 따라 다른 데이터를 보여줘야 하는 경우도 있습니다.

한 번, 이런 경우를 상상해 봅시다. 사용자가 자신의 별명과 좋아하는 색깔을 입력하면, 별명에 입력된 색깔을 적용한 텍스트를 렌더링해주는 웹사이트가 있습니다('고릴라', 'blue'을 입력하면 파란색의 '고릴라'라는 글씨를 보여줍니다). 리액트로 이 부분을 구현하려면 어떻게 해야 할까요? 우선은 입력창이 있고, 결과를 그려주는 컴포넌트(<ColoredNickname /> 이라고 하겠습니다)가 있겠지요. 그렇다면, <ColoredNickname />는 사용자가 입력한 값을 받아와 별명 텍스트는 화면에 그리되, 색깔은 컴포넌트의 style에 적용되어야겠지요. 여기서, 입력받은 '별명'과 '색깔'을 어떻게 컴포넌트에 전달할 수 있을까요? 이 역할을 하는 것이 바로 props 입니다.


0. Props란?

props는 properties를 줄인 표현으로, 컴포넌트에 어떤 값을 전달할 때 사용합니다. props는 해당 컴포넌트를 사용하는 부모 컴포넌트에서 설정합니다. 이렇게 말로만 해서는 잘 와닿지가 않으니, 예시를 보겠습니다.

말머리에서 언급한 예시의 웹사이트를 리액트로 구현해 봅시다. 웹사이트의 메인 컴포넌트인 <App />컴포넌트가 있고, 그 안에 컴포넌트가 입력된 별명과 컬러값에 따라 텍스트에 색상을 적용해 주는 <ColoredNickname />이 있습니다. 아래와 같이 말이예요.

App.js

import React from 'react';
import ColoredNickname from './ColoredNickname';

function App() {
  return (
        <ColoredNickname name="고릴라" color="blue"/>
  );
}

export default App;

여기서, <App /><ColoredNickname />의 부모 컴포넌트이고, ColoredNickname /><App />의 자식 컴포넌트입니다. <ColoredNickname /> 컴포넌트에 두 가지 파라미터와 value가 설정되어있는 것이 보입니다. name의 value는 '고릴라', color의 value는 'blue' 입니다.

이것을 보고 "ColoredNickname 컴포넌트는 name, color라는 두 가지 props를 받도록 작성되어 있겠구나." 라고 생각하셨다면, 정답입니다. 이처럼, 부모 컴포넌트는 자식 컴포넌트를 품은 상태에서 name과 color라는 props를 설정합니다.


<ColoredNickname />는 name, color라는 props를 받아와 렌더링해주도록 설정되어 있습니다. 즉, ColoredNickname 함수의 파라미터로 props를 받는 형태로 작성됩니다. 아래와 같이요.

ColoredNickname.js

import React from 'react';

function ColoredNickname(props) {
  return(
    <div style={{display: 'flex'}}>
      <div>나의 별명은: </div>
      <div style={{color: props.color}}>{props.name}</div>
    </div>
  )}

export default ColoredNickname;

props는 JSX 내부에서 {} 기호로 감싸주면 됩니다.


1. 비구조화 할당을 통한 props 전달

그런데, props값을 컴포넌트에서 조회 또는 사용할 때마다 props.XXX 형태로 사용하는 것은 번거롭습니다. Javascript의 구조 분해 할당(=비구조화 할당) 문법 을 사용해 props 내부 값을 바로 추출할 수 있습니다.

import React from 'react';

function ColoredNickname({ color, nickname }) {
  return(
    <div style={{display: 'flex'}}>
      <div>나의 별명은: </div>
      <div style={{color: color}}>{name}</div>
    </div>
  )
}

export default ColoredNickname;

코드가 조금 더 간결해졌습니다!


2. props의 기본값 설정

만약, <ColoredNickname />에 전달할 color값과 name값을 지정하지 않았을 경우에 보여줄 기본값을 정하고 싶다면, defaultProps라는 값을 설정하면 됩니다.

import React from 'react';

function ColoredNickname({ color, nickname }) {
  return(
    <div style={{display: 'flex'}}>
      <div>나의 별명은: </div>
      <div style={{color}}>{name}</div>
    </div>
  )
}

//props가 입력되지 않을 때 출력할 기본값 설정
ColoredNickname.defaultProps = {
  name: "닉네임",
  color: "green"
}

export default ColoredNickname;

App 컴포넌트에서 name, color 없이 ColoredNickname 컴포넌트를 렌더링하면 다음과 같이 나옵니다.

App.js

import logo from './logo.svg';
import './App.css';
import ColoredNickname from './ColoredNickname';

function App() {
  return (
    <ColoredNickname />
  );
}

export default App;


3. 태그 사이의 내용을 보여주는 children

컴포넌트 태그 사이의 내용을 보고싶을 때는, props.children이라는 개념을 사용하면 됩니다. children이란, 한 컴포넌트의 태그와 태그 사이에 들어간 어떠한 값을 의미합니다.

이제, 우리는 2. props의 기본값 설정의 마지막에 나온 나의 별명 텍스트가 검은 테두리가 있는 네모난 영역 안에 나오도록 하고 싶습니다. 이를 위해, props.children을 사용하는 컴포넌트를 아래와 같이 만들어 봅시다.

(참고로, App.js, ColoredNickname.js, Wrapper.js는 모두 /src 디렉터리 안에 있습니다!)

Wrapper.js

import React from 'react';

function Wrapper() {
  const style = {
    border: '2px solid black',
    padding: 16,
  };

  return <div style={style}></div>
}

export default Wrapper;

이 컴포넌트를 App에서 사용해 보겠습니다.

import logo from './logo.svg';
import './App.css';
import Wrapper from './Wrapper';
import ColoredNickname from './ColoredNickname';

function App() {
  return (
    <Wrapper>
      <Hello />
    </Wrapper>
  );
}

export default App;

자, 한 번 브라우저를 열어 결과를 볼까요?

이럴 수가! 테두리 있는 네모 영역이 나오긴 나왔지만, <ColoredNickname /> 컴포넌트는 보이지 않네요. 이를 해결하려면, Wrapper에서 props.children을 렌더링하면 됩니다.

import React from 'react';

function Wrapper(props) {
  const style = {
    border: '2px solid black',
    padding: 16,
  };

  return <div style={style}>{props.children}</div>
}

//비구조화 할당을 사용하여 간결하게 작성하면 아래와 같습니다.
function Wrapper({ children }) {
  const style = {
    border: '2px solid black',
    padding: 16,
  };

  return <div style={style}>{children}</div>
}

export default Wrapper;

Wrapper 안에 childeren을 렌더링 해 주니 결과가 아래와 같이 잘 나옵니다.

App.js에서 <Wrapper /> 컴포넌트 안에 <ColoredNickname /> 컴포넌트가 들어가 있었죠? 이 <ColoredNickname /> 컴포넌트가 <Wrapper />의 children입니다. 이처럼, props.children은 컴포넌트 태그 안에 있는 내용을 렌더링 해 줍니다.

정리

이번 장의 내용을 정리하겠습니다. 이번 장에서는 props로 컴포넌트에 값을 전달하여 브라우저에 렌더링 해 보았습니다. 또한, 컴포넌트 태그 안에 있는 내용을 렌더링하기 위해 props.children이라는 개념을 사용했습니다.

  • props란 properties의 줄임말로, 컴포넌트에 값을 전달할 때 사용한다.
  • props는 해당 컴포넌트를 사용하는 부모 컴포넌트에서 설정한다.
  • 구조 분해 할당 문법을 사용하면 props.을 생략해도 되어 코드가 보기에 간결하다.
  • props의 기본값을 설정하려면 컴포넌트 함수 밑에 컴포넌트명.defaultProps = { ... } 와 같이 defaultProps를 설정해 준다.
  • 컴포넌트 태그(A) 사이에 들어가있는 내용(B)을 렌더링하려면, A 컴포넌트 함수가 props.children을 받는 형태가 되어야 한다.
profile
부족한 경험을 채우기 위한 나만의 기록 공간

0개의 댓글

관련 채용 정보