이번에는 React의 컴포넌트에서 중요한 개념인 Props
와 State
에 대해 살펴봅시다.
Props
는 컴포넌트 외부에서 컴포넌트에게 주는 데이터이며, State
는 컴포넌트 내부에서 변경할 수 있는 데이터입니다. 둘 다 변경이 발생하면, 렌더링이 다시 일어날 수 있습니다.
추가적으로 render
함수는 Props
와 State
를 바탕으로 컴포넌트를 그립니다. 그리고 Props
와 State
가 변경이 되면, 컴포넌트를 다시 그리게 됩니다. 컴포넌트를 그리는 방법을 기술하는 함수가 바로 render
함수입니다.
참고:
Babel
을 사용하여 컴파일을 하고 있습니다.
// {message: 'Hello!!!'}
function Component(props) {
return (
<div>
<h1>{props.message}</h1>
</div>
);
}
ReactDOM.render(
<Component message='Hello!!!' />,
document.querySelector('#root')
);
위 코드는 함수로 만든 컴포넌트입니다. props
가 매개 변수로 들어가는 것을 볼 수 있습니다.
class Component extends React.Component {
render() {
return (
<div>
<h1>{this.props.message}</h1>
</div>
);
}
}
ReactDOM.render(
<Component message='Hello!!!' />,
document.querySelector('#root')
);
위 코드는 클래스로 만든 컴포넌트입니다. 클래스의 경우, this.props.message
라는 코드를 통해 컴포넌트의 Props
에 접근할 수 있습니다.
<Component message='Hello!!!' />
와 같이 직접 값을 지정하지 않고, defaultProps
값을 설정하여 화면에 출력하는 방법도 있습니다.
function Component(props) {
return (
<div>
<h1>{props.message}</h1>
</div>
);
}
Component.defaultProps = {
message: '기본값'
}
ReactDOM.render(
<Component />,
document.querySelector('#root')
);
Component.defaultProps
에 값을 입력하는 위와 같은 방법은 function
, class
모두 사용이 가능합니다. 다만, class
에서는 아래와 같은 방법도 사용할 수 있습니다.
class Component extends React.Component {
render() {
return (
<div>
<h1>{this.props.message}</h1>
</div>
);
}
static defaultProps = {
message: '기본값!',
}
}
ReactDOM.render(
<Component />,
document.querySelector('#root')
);
물론, 이는 기본값이므로 현재는 기본값!
이 화면에 출력되지만, <Component mesaage='기본값 아님!' />
으로 코딩하여 다시 값을 지정한다면, 기본값 아님!
이라는 Props
값이 출력됩니다.
State
는 현 기준으로는 클래스 컴포넌트에서만 사용할 수 있는 기능으로 봐주시면 됩니다. 물론 Hooks
을 사용하면, 함수에도 사용이 가능하다는 점 참고로 알아주시면 됩니다.
class Component extends React.Component {
state = {
count: 0,
}
render() {
return (
<div>
<h1>{this.props.message}</h1>
<p>{this.state.count}</p>
</div>
);
}
// 라이프사이클: 화면에 올리자마자 바로 실행되는 함수
componentDidMount() {
setTimeout(() => {
// this.state.count = this.state.count + 1
this.setState({
count: this.state.count + 1,
})
}, 1000)
}
위의 내용은 복잡하지만, 이해가 되지 않는 부분은 넘어가셔도 좋습니다. 일단, 해당 코드는 처음에는 숫자 0으로 시작한 state
값이 1초 뒤 1로 변하게 되는 코드입니다.
그리고 state
는 state = {count: 0}
이러한 예시처럼 객체 데이터 형태로 제공이 됩니다. 이는 state
를 초기값으로 설정하는 과정입니다.
이처럼 쉬운 문법으로 작성하는 법도 있지만, 아래처럼 constructor
, super
를 키워드를 사용하여 클래스의 확장 기능을 이용하여 작성하는 방법도 있습니다.
// state = {
// count: 0,
// }
constructor(props) {
super(props);
//
this.state = { count: 0 };
}
그리고 이 state
값을 변하게 만들 때에는 아래의 코드처럼 setState
를 호출하여 값이 바뀐 상태로 render
메소드가 자동으로 호출되게 됩니다. 그렇기 때문에 화면이 다시 그려지게 되는 원리입니다.
// this.state.count = this.state.count + 1
this.setState({
count: this.state.count + 1,
})
이또한 위와 같이 객체를 전달하는 방법 외에 함수를 전달하는 방법도 있습니다. 이를 통해, 항상 setState
가 가장 최신의 state
값을 사용하도록 보장할 수 있습니다. 객체를 전달하게 되면 단순히 0에서 1이 추가되고 끝나지만, 함수를 사용하게 되면 0이 1, 1이 2, 2가 3 이런 식으로 업데이트가 반영될 수 있도록 합니다.
this.setState((previousState)=>{
const newState = { count: previousState.count + 1 }
return newState
})
위와 같이 setState
에 전달하는 함수를 updater
라 부르며, 이를 통해 이전 state
값에 접근할 수 있습니다. setState
호출은 일괄적으로 처리되기 때문에 여러 업데이트 사항이 충돌 없이 차례대로 반영되도록 합니다. 더욱 자세한 사항은 공식 문서를 참고해주시기 바랍니다.