state
- 컴포넌트 내부에서 바뀔 수 있는 값
클래스형 컴포넌트의 state
컴포넌트에 state 설정하기 : constructor 메서드 사용
class Counter extends Component {
constructor(props) {
super(props);
//state의 초기값 설정하기
this.state = {
number: 0,
};
}
- 반드시 super(props)를 함께 호출해야 한다
- this.state 를 사용해 초기값을 설정한다
render
render() {
const { number } = this.state; //state를 조회할 때는 this.state로 조회
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
//state에 새로운 값 넣기: this.setState
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
- this. state : 현재 state 조회
- button onClick : 버튼이 클릭될 때 호출시킬 함수 설정(화살표 함수 사용)
- setState : state 값을 바꿔주는 함수
전체 코드
//Counter.js
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
//state의 초기값 설정하기
this.state = {
number: 0,
};
}
render() {
const { number } = this.state; //state를 조회할 때는 this.state로 조회
return (
<div>
<h1>{number}</h1>
<button
onClick={() => {
//state에 새로운 값 넣기: this.setState
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
//App.js
import Counter from './Counter';
const App = () => {
return <Counter />;
};
export default App;
state 객체 안에 여러 값이 있을 때
//Counter.js
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
//state의 초기값 설정하기
this.state = {
number: 0,
fixedNumber: 0, // fixedNumber 추가
};
}
render() {
const { number, fixedNumber } = this.state; // fixedNumber 추가
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
//state에 새로운 값 넣기: this.setState
this.setState({ number: number + 1 }); // fixedNumber 추가로 넣지 않음
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
- this.setState 함수를 사용할 때 인자로 전달되는 개체 내부에 fixedNumber를 넣지 않음
- => this.setState 함수는 인자로 전달된 객체 안에 있는 값만 바꿔준다
state의 초기값을 지정하는 또다른 방법
- constructor 없이 state를 사용할 수 있다
//Counter.js
import React, { Component } from 'react';
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (...);
}
}
export default Counter;
this.setState에 함수 인자 전달하기
- this.setState를 사용하여 state 값을 업데이트 할 때는 상태가 비동기적으로 업데이트 된다
- 숫자를 2씩 올리고 싶을 때
onClick={() => {
//state에 새로운 값 넣기: this.setState
this.setState({ number: number + 1 });
this.setState({ number: this.state.number + 1 });
}}
- this.setState를 쓴다해서 숫자가 바로 업데이트 되지 않기 때문에 숫자가 1씩만 더해진다
- 해결 방법 : 아래와 같이 함수를 인자로 넣어주면 된다
this.setState((prevState,props) => {
return {
// 업데이트 하고 싶은 내용
};
});
- prevState는 기존 상태를, props는 현재 지니고 있는 props를 의미한다
- props는 불필요하다면 생략 가능하다
<button
onClick={() => {
//state에 새로운 값 넣기: this.setState
this.setState((prevState) => {
return {
number: prevState.number + 1,
};
});
this.setState((prevState) => ({
number: prevState.number + 1,
}));
}}
>
- 위의 두 코드는 표현만 다를 분 완전히 똑같은 기능을 한다
- return 이 생략된 아래 코드는 함수에서 바로 객체를 반환한다는 의미이다
- 위와 같이 하면 숫자가 2씩 올라간다
this.setState가 끝난 후 특정 작업 실행하기
- setState의 두번째 파라미터로 콜백 함수를 등록하여 작업을 실행
//Counter.js
import React, { Component } from 'react';
class Counter extends Component {
state = {
number: 0,
fixedNumber: 0,
};
render() {
const { number, fixedNumber } = this.state;
return (
<div>
<h1>{number}</h1>
<h2>바뀌지 않는 값 : {fixedNumber}</h2>
<button
onClick={() => {
//state에 새로운 값 넣기: this.setState
this.setState(
{
number: number + 1,
},
() => {
console.log('setState 호출');
console.log(this.state);
}
);
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
결과
함수 컴포넌트에서 useState 사용하기
배열 비구조화 할당
- 배열 안에 들어있는 값을 쉽게 추출할 수 있도록 해주는 문법
const arr = [1, 2];
const one = arr[0];
const two = arr[1];
- 배열 비구조화할당 사용
const arr = [1, 2];
const [one, two] = arr;
useState 사용하기
import { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const onClickEnter = () => setMessage('안녕!');
const onClickLeave = () => setMessage('잘가!');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1>{message}</h1>
</div>
);
};
export default Say;
- useState 함수의 인자 : 상태의 초깃값 넣기. 값의 형태는 상관없다.
- 함수를 호출하면 배열이 반환된다
- 첫번째 원소(message) : 현재 상태
- 두번째 원소(setMessage) : 상태를 바꿔주는 함수(=세터(Setter)함수)
- 이름은 자유롭게 정해줘도 된다
한 컴포넌트에서 useState 여러번 사용하기
- 한 컴포넌트 내에서 여러번 사용 가능하다
import { useState } from 'react';
const Say = () => {
const [message, setMessage] = useState('');
const onClickEnter = () => setMessage('안녕!');
const onClickLeave = () => setMessage('잘가!');
const [color, setColor] = useState('black');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1 style={{ color }}>{message}</h1>
<button style={{ color: 'red' }} onClick={() => setColor('red')}>
빨간색
</button>
<button style={{ color: 'green' }} onClick={() => setColor('green')}>
초록색
</button>
<button style={{ color: 'blue' }} onClick={() => setColor('blue')}>
파란색
</button>
</div>
);
};
export default Say;
결과
- 버튼에 style없애고 코드만 보면 이런 모양
const [color, setColor] = useState('black');
return (
<div>
<button onClick={onClickEnter}>입장</button>
<button onClick={onClickLeave}>퇴장</button>
<h1 style={{ color }}>{message}</h1>
<button onClick={() => setColor('red')}>빨간색</button>
<button onClick={() => setColor('green')}>초록색</button>
<button onClick={() => setColor('blue')}>파란색</button>
</div>
state 사용 시 주의사항
- 값을 변경할 때에는 setState 또는 useState를 통해 전달받은 세터 함수를 사용해야 한다
- 배열이나 객체를 업데이트해야 할 때에는 사본을 만들고 그 사본에 값을 업데이트 한 후 사본의 상태를 setState 혹은 세터 함수를 통해 업데이트한다.
- 객체의 사본을 만들 때에는 spread 연산자라 불리는 `...`을 사용한다
- 배열의 사본을 만들 때에는 배열의 내장함수를 사용한다
- 올바른 예시
// 객체
const object = { a: 1, b: 2, c: 3 };
const nextObject = { ...object, b: 2 }; // 사본을 만들어서 b 값만 덮어씀
// 배열
const array = [
{ id: 1, value: true },
{ id: 2, value: true },
{ id: 3, value: false },
];
// 새 항목 추가
let nextArray = array.concat({ id: 4 });
// id가 2인 항목 제거
nextArray.filter((item) => item.id !== 2);
// id가 1인 항목의 value를 false로 변경
nextArray.map((item) => (item.id === 1 ? { ...item, value: false } : item));
- 잘못된 사용 예시
import { useState } from 'react';
// 클래스형
this.state.number = this.state.number + 1;
this.state.array = this.array.push(2);
this.state.object.value = 5;
// 함수형
const [object, setObject] = useState({ a: 1, b: 1 });
object.b = 2;
'개발새발개발 > React' 카테고리의 다른 글
React - ref (0) | 2024.12.29 |
---|---|
React 이벤트 핸들링 (1) | 2024.12.28 |
React 컴포넌트(Component), 화살표 함수, Snippet (1) | 2024.12.24 |
React JSX 문법과 ESLint, Prettier 적용법 (0) | 2024.12.23 |
React JSX란? (0) | 2024.12.22 |
댓글