그럼에도 불구하고

👨‍💻

[React] state란? 본문

React/React basics

[React] state란?

zenghyun 2023. 3. 29. 20:40

오늘은 state란 무엇인지 알아보겠습니다.

 

 

 

[ prop / state ]

React 공식 문서에 따르면 prop와 state를 다음과 같이 정의하고 있습니다. 

prop(properties의 줄임말)와 state는 일반 자바스크립트 객체다. 두 객체 모두 렌더링 결과물에 영향을 주는 정보를 
갖고 있는데 한 가지 중요한 방식에서 차이가 있다. props는 (함수 매개변수처럼) 컴포넌트에 전달되는 반면 state는 
(함수 내 선언된 변수처럼) 컴포넌트 안에서 관리한다. React에서 this.props와 this.state는 모두 렌더링된 값을
나타낸다. 다시 말해 현재 화면에 보이는 걸 말한다

 

state와 prop을 정리하면 아래와 같습니다.  

 

  • 둘 다 일반 자바스크립트 객체이다.
  • state는 컴포넌트 안에서 사용된다.
  • prop은 컴포넌트에 매개변수처럼 전달하는 것이다. 
  State Props
유스케이스 뷰에 렌더링돼야 하는 컴포넌트의 데이터를 저장하는데 사용한다.  데이터, 이벤트 핸들러를 자식 컴포넌트에 전달하는 데 사용한다.
가변성 상태는 데이터를 보유하고 시간이 지남에 따라 변경될 수 있다. props는 바뀔 수 없으며, 한 번 설정되면 props를 변경할 수 없다.
업데이트 이벤트 핸들러는 일반적으로 state를 업데이트한다. 상위 컴포넌트는 하위 컴포넌트에 대한 props를 설정한다.

 

[ state ] 

1
2
3
4
5
6
7
8
9
10
11
import { useState } from 'react';
 
function Example() {
    const [count, setCount] = useState(0);
    return (
        <div>
            <p>버튼을 {count}번 눌렀습니다.</p>
            <button onClick={() => setCount(count + 1)}>클릭</button>
        </div>
    );
}
cs

 

State는 컴포넌트 내에서 지속적으로 변경이 일어나는 값을 관리하기 위해 사용합니다. ( 변동성 ) 

즉, 개발자가 의도한 동작에 의해 변할 수도 있고, 사용자의 입력에 따라 새로운 값으로 변경될 수도 있습니다. 

State 값이 변경되고 재 렌더링이 필요한 경우에는 React가 자동으로 계산하여 변경된 부분을 렌더링 합니다. 

 

 

💡 state 사용하기

 

1
2
3
4
5
6
import { useState } from "react";
 
const App = () => {
    const [value, setValue] = useState(초기값);
    return ...
}
cs

 

 state의 값을 변경하기 위해서는 반드시 setState함수를 사용해야 합니다. 또한, state 값을 임의로 변경해서는 안됩니다. 

 

만약, state의 값을 직접 변경하게 되면 React가 Component를 다시 렌더링 할 타이밍을 알아차리지 못합니다.

그렇기 때문에 반드시 setState 함수를 이용하여 값을 변경해줘야 합니다. setState 함수의 호출은 React에게 다시 렌더링을 해달라는 명령을 하는 것과 같습니다.

 

 

💡 state를 변경하는 방법 

 

1
2
3
4
5
6
7
8
9
10
// 1. setState 내에 변경할 값을 넣기
const [count, setCount] = useState(0);
setCount(count + 1);
 
// 2. setState에 함수를 넣기
const [count, setCount] = useState(0);
 
setCount((current) => {
    return current + 1
})
cs

 

setState 함수에는 변경할 값을 직접 넣는 방법과 함수를 넣는 방법이 있습니다.

함수를 넣는 경우 함수가 반환(return)하는 값으로 State가 변경됩니다.

 

현재 값을 기반으로 State를 변경하고자 하는 경우 함수를 넣는 방법을 권장합니다.

 

참고

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
incrementCount() {
  // 주의: 이 코드는 예상대로 동작하지 *않을 것*입니다.
  this.setState({count: this.state.count + 1});
}
 
handleSomething() {
  // `this.state.count`가 0에서 시작한다고 해봅시다.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // React가 컴포넌트를 리렌더링할 때 `this.state.count`는 3이 될 것 같은 예상과 달리 1이 됩니다.
 
  // 이것은 `incrementCount()` 함수가 `this.state.count`에서 값을 읽어 오는데
  // React는 컴포넌트가 리렌더링될 때까지 `this.state.count`를 갱신하지 않기 때문입니다.
  // 그러므로 `incrementCount()`는 매번 `this.state.count`의 값을 0으로 읽은 뒤에 이 값을 1로 설정합니다.
 
  // 
cs

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
incrementCount() {
  this.setState((state) => {
    // 중요: 값을 업데이트할 때 `this.state` 대신 `state` 값을 읽어옵니다.
    return {count: state.count + 1}
  });
}
 
handleSomething() {
  // `this.state.count`가 0에서 시작한다고 해봅시다.
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
 
  // 지금 `this.state.count` 값을 읽어 보면 이 값은 여전히 0일 것입니다.
  // 하지만 React가 컴포넌트를 리렌더링하게 되면 이 값은 3이 됩니다.
}
cs

 

 

 

💡 Object, Array를 갖는 state를 만들 때 주의사항 

 

 

틀린 예 

 

1
2
3
4
5
6
const [user, setUser] = useState({name"zenghyun", grade: 1})
 
setUser((current) => {
    current.grade = 2// 이렇게 하면 안 된다.
    return current;
})
cs

 

Object를 값으로 갖는 State도 만들 수 있습니다. 그러나 예시의 경우 React가 state의 변경을 감지하지 못하는데, user object안의 grade가 변경되었지만 user 자체는 변경되지 않았기 때문입니다. 

 

올바른 예

 

1
2
3
4
5
6
7
const [user, setUser] = useState({name'zenghyun', grade: 1 })
 
setUser((current) => {
    const newUser = { ...current }
    newUser.grade = 2
    return newUser
})
cs

 

위처럼 기존 user의 내용을 새로운 object에 담고 grade를 변경합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import React, { useState } from 'react';
 
function App() {
  const [person, setPerson] = useState({
    name"zenghyun",
    count: 0
  });  
 
  return (
    <div className="App">
        <button onClick={() => {
            setPerson((current) => {
                const newPerson = { ...current };
                newPerson.count = newPerson.count + 1;
                return newPerson;
            })
        }}>클릭</button>
        <span>{person.name}님이 버튼을 {person.count}회 클릭하였습니다.</span>
    </div>
  );
}
 
cs

 

 

ref: https://ko.reactjs.org/docs/faq-state.html

'React > React basics' 카테고리의 다른 글

[React] Portal이란?  (0) 2023.04.06
[React] htmlFor란?  (0) 2023.04.06
[React] Styled Component란?  (0) 2023.04.04
[React] Components와 Props란?  (0) 2023.03.22
[React] React란?  (0) 2023.03.17
Comments