상위 컴포넌트가 하위 컴포넌트에게 값을 전달할 때 사용합니다.
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;

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

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) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.