상위 컴포넌트가 하위 컴포넌트에게 값을 전달할 때 사용합니다.
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) : 기초부터 실전까지(이정환)"
를 정리한 내용입니다. 쉽게 잘 설명해주시니 여러분도 강의를 듣는 것을 추천드립니다.