리액트 - props와 state
velopert님의 블로그에서 리액트 기초 과정을 보고 리액트를 알아가는 시간을 가졌으며,
해당 포스팅은 위 과정을 이해한대로 정리한 것이다.
(https://velopert.com/reactjs-tutorials)
리액트 컴포넌트에서 다루는 데이터는 props와 state 두 개로 나뉜다.
props : 부모 컴포넌트가 자식 컴포넌트에게 주는 값 (받아온 값은 직접 수정 불가능 ❌)
state : 컴포넌트 내부에서 선언한 값 (값 변경 가능 ⭕️)
새 컴포넌트 만들기
MyName이라는 이름의 컴포넌트를 만들자.
import React, { Component } from 'react';
class MyName extends Component{
render(){
return(
<div>
안녕하세요. 제 이름은 <b>{this.props.name}</b>입니다.
</div>
);
}
}
export default MyName;
이때 this.
키워드를 통해 자신이 받아온 props값을 조회할 수 있으며, name이라는 props를 보여준다.
App.js를 아래와 같이 수정하고 실행하자.
import MyName from './MyName';
function App() {
return (
<MyName name="리액트"/>
);
}
제대로 잘 받아오는 것을 볼 수 있다.
defaultProps
props의 기본값을 설정할 수 있다.
static defaultProps = {
name: '기본이름'
}
or
MyName.defaultProps = {
name: '기본이름'
}
함수형 컴포넌트
함수형태로 컴포넌트를 작성한다.
const MyName = ({ name }) => {
return(
<div>
저의 이름은 {name} 입니다.
</div>
);
};
state와 LifeCycle이 빠져있다는 것이 클래스형 컴포넌트와의 차이점이다.
초기 마운트가 미세하게 빠르고, 메모리 자원을 덜 사용하는 장점이 있으나, 컴포넌트를 무수히 많이 렌더링 하는 경우가 아니라면 큰 차이는 없다.
state
동적인 데이터를 다룰 때 사용한다.
class Counter extends Component {
state = {
number: 0
}
handelIncrease = () => {
this.setState({
number: this.state.number + 1
});
}
handelDecrease = () => {
this.setState({
number: this.state.number - 1
});
}
render(){
return(
<div>
<h1>카운터</h1>
<div>값: {this.state.number}</div>
<button onClick={this.handelIncrease}>+</button>
<button onClick={this.handelDecrease}>-</button>
</div>
);
}
}
컴포넌트의 state를 정의할 때는 class fields 문법을 사용해서 정의한다.
class fields를 사용하지 않는다면, 아래와 같이 사용한다.
class Counter extends Component{
constructor(props){
super(props);
this.state. = {
number : 0
}
}
}
constructor를 작성하면, 기존의 클래스 생성자를 덮어쓰게 된다.
리액트 컴포넌트가 지니고 있던 실행자를 super를 통해 미리 실행하고,
그 다음 우리의 작업인 state를 설정할 수 있도록 작성하였다.
class fields와 constructor를 모두 사용한다면, 실행 순서는 class fields -> constructor이다.
메소드 작성
handelIncrease = () => {
this.setState({
number: this.state.number + 1
});
}
handelDecrease = () => {
this.setState({
number: this.state.number - 1
});
}
만약 아래와 같은 방식으로 메소드를 작성하면, 함수에 버튼 클릭이벤트가 전달 되는 과정에서 this와의 연결이 끊기게 된다.
handelIncrease(){
this.setState({
number: this.state.number + 1
});
}
handelDecrease(){
this.setState({
number: this.state.number - 1
});
}
즉, this가 undefined로 나타나는 것이다.
이를 해결하려면 constructor를 아래와 같이 수정한다.
constrictor(props){
super(props);
this.handleIncrease = this.handleIncrease.bind(this);
this.handleDecrease = this.handleDecrease.bind(this);
}
setState
state의 값을 바꾸기 위해서는 this.setState를 무조건 거쳐야한다.
setState는 객체로 전달되는 값만 업데이트를 해준다.
state = {
number:0,
foo: 'bar'
}
위와 같은 코드를 작성하고, this.setState({number:1});
를 하면 foo는 그대로 남고, number값만 업데이트 되는 것이다.
setState는 또한 객체의 깊숙한 곳까지 확인하지 못하므로
아래와 같은 코드는 기존 foo 객체만 바뀔뿐이다.
state = {
number:0,
foo: {
foobar: 2
}
}
위와 같은 상황에서는 아래와 같이 코드를 수정해야 한다.
state = {
number:0,
foo: {
...this.state.foo,
foobar: 2
}
}
...
은 자바스크립트의 전개연산자이다. 기존의 객체안 내용을 해당 위치에 풀어준다는 뜻이다.
그 다음, 설정하고 싶은 값을 또 넣어주면 해당 값을 덮어쓰게 된다.
setState에 객체 대신 함수 전달하기
기존 코드는 this.state를 중복 조회하므로 아래와 같이 변경할 수 있다.
this.setState(
(state) = > ({
number: state.number
})
);
비구조화 할당이라는 문법을 사용하면 더 나아가 아래와 같은 코드로 변경이 가능하다.
this.setState(
({number}) = > ({
number: number + 1
})
);
이 중 마음에 드는 코드를 골라 사용하면 된다.
handelIncrease = () => {
const {number} = this.state;
this.setState({
number: number + 1
});
}
handelDecrease = () => {
this.setState({
({number}) = > ({
number: number - 1
})
});
}
이벤트 설정
리액트와 html의 이벤트 함수 설정시 차이점 (주의 ❗️)
html
<button onclick="alert('hello');">Click Me</button>
<button onclick={this.handleIncrease}>+</button>
- 이벤트 이름은 camelCase 형식으로 설정 ex) onClick, onMouseDown
- 이벤트에 전달하는 값은 함수!
onClick={this.handleIncrease()}
와 같은 방식은 렌더링 → 함수호출 → setState → 렌더링의 무한 반복이 된다.
이제 오늘 배운 내용을 아래와 같이 적용하고 실행해보자.
import Counter from './Counter';
function App() {
return (
<Counter/>
);
}
export default App;
Author And Source
이 문제에 관하여(리액트 - props와 state), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yeah7598/리액트-props와-state저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)