공부/React.js

[React.js] Props

데부한 2022. 5. 7. 17:24
반응형

 

React 게시글은 대부분 인프런의 '한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지' 강의를 기반으로 내용을 정리했습니다.

 

Props

Props는 State와 더불어 React의 대표적인 기능 중 하나이다. Props는 컴포넌트에게 데이터를 전달하는 기본적이고 효율적인 기능이다. Props는 Properties의 줄임말이다.

//import './App.css';
import MyHeader from './MyHeader';
import React from 'react';
import Counter from './Counter';

function App() {

  const number = 5;

  return (
    <div>
      <MyHeader />
      <Counter initialValue={5}/> <!-- Counter 컴포넌트에 값 전달-->
    </div>
  );
}

export default App;

위의 코드를 보면 Counter 컴포넌트에 initialValue={5}라는 코드를 추가했다. initialValue를 추가하면 App 컴포넌트에서 Counter 컴포넌트로 값을 넘길 수 있다.

 

Counter 컴포넌트에서 부모로부터 받아온 값을 전달 받기 위해 매개변수를 하나 넣어준다. 그리고 console에 찍어보면 props 변수에 객체로 전달된 값을 볼 수 있다.

import React, {useState} from 'react';

const Counter = (props) =>{ // 매개변수를 이용해 전달된 값을 받는다.
    console.log(props);
    const [count, setCount] = useState(0);

    const onIncrease = () => {
        setCount(count+1);
    }

    const onDecrease = () => {
        setCount(count-1);
    }

    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
        </div>
    )
};

export default Counter;

 

객체로 전달되기 때문에 여러 개의 Props를 보내도 괜찮다.

<Counter a={1} initialValue={5}/>

객체에서 값을 꺼내오고 싶으면 일반적으로 사용하는 점 표기법으로 꺼내오면 된다.

const [count, setCount] = useState(props.initialValue);

 

Props 값이 여러 개면 하나하나 다 작성하기 힘드니 객체를 만들어 스프레드 연산자를 이용해 전달해도 된다.

function App() {

  const number = 5;

  const counterProps = {
    a : 1,
    b : 2, 
    c : 3, 
    d : 4,
    e : 5,
    initialValue : 5
  };

  return (
    <div>
      <MyHeader />
      <Counter {...counterProps}/> <!-- 객체를 펼쳐주는 스프레드 연산자-->
    </div>
  );
}

export default App;

 

만약 값을 전달할 때 initialValue를 빼먹게 되면 어떻게 될까? 부모로부터 initialValue를 전달받지 못했는데 Counter 컴포넌트에서는 그 값을 사용할 경우 Counter 컴포넌트의 initialValue에는 undefined 상태이다. 그래서 그 상태에서 +나 -버튼을 누르면 NaN이 출력된다. 이 현상은 명백한 오류이다. 우리는 값이 넘어오지 않는 상황까지 고려하여 개발해야한다. 그럼 어떻게 해결할까? 바로 defaultProps를 이용하면 된다.

import React, {useState} from 'react';

const Counter = (props) =>{
    console.log(props);
    const [count, setCount] = useState(props.initialValue);

    const onIncrease = () => {
        setCount(count+1);
    }

    const onDecrease = () => {
        setCount(count-1);
    }

    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
        </div>
    )
};

<!--defaultProps 추가-->
Counter.defaultProps = {
    initialValue : 0,
};

export default Counter;

defaultProps가 있어 부모로부터 initialValue 값이 넘어오지 않더라도 0으로 초기화되어 기존 기능을 오류 없이 그대로 이용할 수 있다.

참고로 비구조화 할당 방법을 이용하여 객체에서 값 하나만 사용하면 될 경우는 아래와 같이 작성하면된다.

const Counter = ({ initialValue }) =>{

 

 

그럼 이제 새로운 예제를 만들어보자. 부모(Counter)로부터 받아온 initialValue의 값이 짝수인지 홀수인지 판별하는 프로그램이다. 먼저 Counter에 컴포넌트를 추가하자.

    return (
        <div>
            <h2>{count}</h2>
            <button onClick={onIncrease}>+</button>
            <button onClick={onDecrease}>-</button>
            <OddEvenResult count={count} /> <!-- OddEvenResult 컴포넌트 추가, count 값 넘겨주기-->
        </div>
    )

 

그리고 OddEvenResult를 구현해보자.

const OddEvenResult = ({count}) => {
    console.log(count);
    return <>{count % 2 === 0 ? "짝수" : "홀수"}</>
};

export default OddEvenResult;

잘 된다.

버튼을 누를 때마다 count의 값이 짝수인지 홀수인지 잘 출력된다. 리액트에서 컴포넌트는 부모에서 내려주는 Props의 값이 변경되면 그 밑의 자식들을 다시 호출하면서 다시 렌더(리렌더)를 하게된다.

 

Props는 다양한 타입을 전달할 수 있는데 컴포넌트도 전달할 수가 있다. Container.js를 만들어 화면에 딱 붙어있는 요소들을 예쁘게 만들어보자.

const Container = ({children}) => {
    return <div style={{margin:20, padding: 20, border:"1px solid black"}}>
        {children}
    </div>
}

export default Container;

 

App.js에서도 수정해줘야한다.

  return (
    <Container> <!--Container 컴포넌트로 감싸주기-->
      <div>
        <MyHeader />
        <Counter {...counterProps}/>
      </div>
    </Container>

  );

그러면 설정한 CSS가 적용되어 이쁘게 나온다.

 

반응형