[React] Props

이재훈·2023년 6월 6일
0

React

목록 보기
5/27

Props

상위 컴포넌트가 하위 컴포넌트에게 값을 전달할 때 사용합니다.

Props 예시

Counter.js

import React, {useState} from 'react';

const Counter = () => {

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

    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;

App.js

import './App.css';
import MyHeader from './MyHeader';
import Counter from './Counter';
function App() {
  return (
    <div>
      <MyHeader/>
      <Counter/>
    </div>
  );
}

export default App;

위 코드는 이전 게시글에서 만들었던 버튼을 눌러 숫자를 가감하는 프로그램입니다. 여기서 App 컴포넌트에서 Counter 컴포넌트에게 number 타입의 값을 보내고 그 값을 초기값으로 사용해보도록 하겠습니다.

App.js

import './App.css';
import MyHeader from './MyHeader';
import Counter from './Counter';
function App() {
  return (
    <div>
      <MyHeader/>
      <Counter initialValue={5}/>
    </div>
  );
}

export default App;

Prop 기능을 사용하여 자식 컴포넌트에게 initialValue 이름으로 5의 값을 전달할 수 있습니다.

그 전달한 값을 출력해보도록 하겠습니다.

Counter.js

import React, {useState} from 'react';

const Counter = (props) => {

    console.log(props);
    const [count, setCount] = useState(0);

    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;


객체에 담겨서 Counter.js로 넘어가는 것을 확인할 수 있습니다. 여러 값을 보내고 싶다면 아래와 같이 하면 됩니다.

App.js

import './App.css';
import MyHeader from './MyHeader';
import Counter from './Counter';
function App() {
  return (
    <div>
      <MyHeader/>
      <Counter name={'jay'} initialValue={5}/>
    </div>
  );
}

export default App;


여러 개의 값을 보내도 객체에 담겨서 Counter.js로 넘겨지게 됩니다.
Counter.js에서 넘겨지는 값을 사용하려면 점표기법을 사용하면 됩니다.

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

여러 개의 값을 전달할 때는 아래와 같이 스프레드 연산자를 사용하면 가독성이 더 좋아집니다.

App.js

import './App.css';
import MyHeader from './MyHeader';
import Counter from './Counter';
function App() {

  const CounterProps = {
    a: 1,
    b: 2,
    c: 3,
    name: 'jay',
    initialValue: 5
  }


  return (
    <div>
      <MyHeader/>
      <Counter {...CounterProps}/>
    </div>
  );
}

export default App;

스프레드 연산자를 사용하였기 때문에 전달 받은 값을 받을 때도 비구조화 할당을 사용하여 값을 받을 수 있습니다.

Counter.js

import React, {useState} from 'react';

const Counter = ({ initialValue }) => {

    console.log(initialValue);
    const [count, setCount] = useState(initialValue); // 5

    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;

만약에 initialValue 이 undefined 이면 화면에 아무것도 출력되지 않습니다. 이럴 때는 defaultProps를 사용하면 default value를 설정할 수 있습니다.

Counter.js

import React, {useState} from 'react';

const Counter = ({ initialValue }) => {

    console.log(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;

위 코드처럼 defualtProps를 사용하여 에러를 방지할 수 있습니다. Props를 사용하면 정적인 데이터와 동적인 데이터를 자식 컴포넌트에게 전달할 수 있습니다.

이제 Counter.js의 자식 컴포넌트 OddEvenResult.js 를 만들고 OddEvenResult.js에서는 count 값을 받아 홀수 짝수 값을 찍는 컴포넌트를 만들어 보겠습니다.

OddEvenResult.js

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

export default OddEvenResult;

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;

원하는대로 잘 작동하는 것을 확인할 수 있습니다. 하지만 콘솔에 값이 두번씩 출력되는 것을 보고 저는 당황했습니다.

그 이유는 바로 strictMode 때문!!!!

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

index.js를 보면 app 태그를 React.StrictMode로 감싸고 있는 것을 확인할 수 있습니다.
StrictMode는 react에서 제공하는 검사 도구라고 생각하면 됩니다. 개발 모드일 때만 디버그를 하여 해당 태그로 감싸져 있는 부분은 자손까지 검사한다고 합니다. 안전하지 않은 생명주기를 가진 컴포넌트, 권장되지 않는 부분을 미리 잡을 수 있게 해주는 기능입니다.

create-react-app 명령어로 react app을 만들면 기본적으로 생성되는 태그라고 합니다.

해당 태그를 지우면 로그가 1번씩 출력되는 것을 알 수 있습니다.

리렌더링 규칙

  1. 컴포넌트가 가진 state가 변경될 때마다
  2. 나에게 내려오는 props가 변경될 때마다
  3. 내 부모가 리렌터딩이 될 때마다

props는 무엇이든지 전달이 가능합니다. 컴포넌트를 props로 전달하는 예제를 작성해보도록 하겠습니다.

src/Container.js

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

export default Container;

App.js

import './App.css';
import MyHeader from './MyHeader';
import Counter from './Counter';
import Container from './Container';
function App() {

  const CounterProps = {
    a: 1,
    b: 2,
    c: 3,
    name: 'jay',
    initialValue: 0
  }

  return (
    <Container>
      <div>
        <MyHeader/>
        <Counter {...CounterProps}/>
      </div>
    </Container>
  );
}

export default App;

Container.js 파일을 만들어 css를 설정하고 App.js에 Container 태그로 나머지 태그들을 감싸보았습니다.

원하는 css를 props를 사용하여 적용해 보았습니다. 정리를 하자면 props는 모든 것을 전달할 수 있고 거기에는 react.element도 가능하다. 라고 이해하시면 됩니다.


해당 게시글은 인프런 강의
"한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.

strict mode 참고 블로그

profile
부족함을 인정하고 노력하자

0개의 댓글