본문 바로가기
Front-End/React

[ React ] React 입문 ④ Props

by 2CHAE._.EUN 2022. 9. 17.

[ Props ]

 

state( 상태 ) : 컴포넌트가 가지는 동적인 데이터

 

Props : 컴포넌트에 데이터를 전달하는 방법

 

count의 초기 값을  App 컴포넌트에서 Counter 컴포넌트에게 전달하는 값으로 사용해야할 경우 Props 기능을
사용해야한다. → 부모 컴포넌트에서 자식 컴포넌트에게 initialValue라는 값을 전달할 수 있음

 

App.js

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

function App() {

  return (
    <div className="App">
      <h2>+를 누르면 1 증가, -를 누르면 1 감소</h2>
      <Counter initialValue={5}/>
    </div>
  );
}

export default App;

 

즉, 모 컴포넌트에서 자식 컴포넌트에게 어떤 값을 이름을 붙여서 전달하는 방식을 Props라고 한다.

하지만 전달만 해서는 자동으로 초기값으로 적용이 되지 않는다. 자식 컴포넌트에서는 부모에서 내려준 Props를

매개변수로 받아와서 사용을 해야한다. Props는 몇 개가 전달이 되든 객체 안에 담겨서 전달이 되므로 점 표기법으로

접근해서 사용해야한다. 

 

Counter.js

import React,{useState} from 'react';

const Counter = (props) => {

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

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

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

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

export default Counter;

 

 

자식 컴포넌트에게 전달해야할 Props가 매우 많이 존재할 경우 객체로 만들어서 spread 연산자를 사용해 전달해

줄 수  있다. 받는 쪽인 자식 컴포넌트에서도 비구조화 할당을 통해 객체를 받을 수 있다.

 

App.js

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

function App() {

  const countProps = {
    a : 1,
    b : 4,
    c : 7,
    d : 10,
    initialValue : 0
  };

  return (
    <div className="App">
      <h2>+를 누르면 1 증가, -를 누르면 1 감소</h2>
      <Counter {...countProps}/>
    </div>
  );
}

export default App;

 

Counter.js

import React,{useState} from 'react';

const Counter = ({c}) => {

    const [count, setCount] = useState(c);

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

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

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

export default Counter;

 

인자로 받은 props 객체에서 {}안에 필요한 값만 꺼내서 사용하면 된다. 

 

 


< 특정 Props가 undefined로 전달될 수 있는 경우 해결하기 >

 

자식 컴포넌트에 defaultProps를 설정해놓으면 부모 컴포넌트에서 전달 받지 않은 Props일지라도 defaultProps에

의해 고정이 되어 사용할 수 있다.

 

Counter.js

import React,{useState} from 'react';

const Counter = ({ initialValue }) => {

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

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

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

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

Counter.defaultProps = {
    initialValue : 0
};

export default Counter;

 

즉, defaultProps 기능을 사용하면 전달받지 못한 Props의 기본 값을 설정해서 에러를 방지할 수 있다.

 


Props는 자식 컴포넌트에게 정적인 데이터 뿐만 아니라 동적인 데이터도 전달할 수 있다. 

 

동적인 데이터 : state 

 

Counter.js

import React,{useState} from 'react';
import OddEvenResult from './OddEvenResult';

const Counter = ({ initialValue }) => {

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

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

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

    return (
        <div>
            <h2>{count}</h2>
            <button onClick={plus}>+</button>
            <button onClick={minus}>-</button>
            <OddEvenResult count={count}/>
        </div>
    );
};

Counter.defaultProps = {
    initialValue : 0
};

export default Counter;

 

OddEvenResult.js

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

export default OddEvenResult;

 

 

리액트의 컴포넌트는 부모가 내려주는 Props가 변경이 되면 다시 랜더를 하기 때문에 reRender가 일어난다. 

* 부모 컴포넌트의 state만 바뀌어도 자식 컴포넌트도 독립적으로 reRender된다. 

 

* 리액트의 컴포넌트가 reRender 되는 순간

1. 컴포넌트 본인이 관리하고 본인이 가진 state가 바뀔 때

2. 자식 컴포넌트에게 내려오는 Props가 바뀔 때

3. 부모 컴포넌트가 reRender되면 자식 컴포넌트도 reRender가 된다.

 


Props로는 무엇이든 전달할 수 있기 때문에 컴포넌트 자체도 전달할 수 있다.

→ 컴포넌트 자체를 Props로 전달해서 컴포넌트를 컴포넌트로 감쌀 수 있다.

 

Container.js

const Container = ({ children }) => {
    return (
    <div style={ { padding:10, border:"2px solid black " }}>
        {children} 
    </div> 
    ); 
}

export default Container;

 

App.js

import './App.css';
import Counter from './Count';
import React from 'react';
import Container from './Container';
import Myheader from './Myheader';

function App() {

  const countProps = {
    a : 1,
    b : 4,
    c : 7,
    d : 10,
    initialValue : 0
  };

  return (
    <Container>
      <div className="App">
        <Myheader/>
        <Counter {...countProps}/>
      </div>
    </Container>
  );
}

export default App;

 

컴포넌트 사이에 HTML, JSX 요소들을 배치할 수 있다.

 

Container 컴포넌트 안에 있는 자식으로 배치된 요소들은 모두 Container 컴포넌트의 children이라는 Props로

전달이 된다. children에 HTML와 JSX 요소들이 전달이 되면 children을 값처럼 활용해서 출력할 수 있다.

 

App.css

.App{
  border : 1px solid yellow;
  background-color: cadetblue;
}

h2 {
  color: aquamarine;
  text-align: center;
}

.count{
  text-align: center;
  font-weight: bold;
  font-size: 20px;
  padding: 10px;
  color: aquamarine;
}