state와 필요한 이유
- 함수 컴포넌트에서 내부적으로 상태를 관리해야 하는 일이 필요하다. 이를 위해 필요한 것이 state다
- state는 컴포넌트의 내부에서 변경 가능한 데이터를 다루기 위해 사용하는 객체라고 할 수 있다
- const, let 등으로 선언한 변수와 다르게 state는 값이 변하면 관련 있는 컴포넌트들이 re-rendering 되어 화면이 바뀐다
useState()
import React, { useState } from "react"; // Hook
const [state, setState] = useState(); // [값, 값을 변경할 때 쓰는 함수]
- 일반적으로 리액트에서는 '유동적인 데이터'는 변수에 담아서 사용하지 않고, useState라는 리액트 Hook함수를 사용하여 state라는 저장 공간에 담아 사용한다.
- useState는 배열을 리턴하는데 배열에는 두 가지 값(값, 값을 변경할 때 쓰는 함수)이 들어있다.
- 이를 구조 분해 할당하면 state를 함수 컴포넌트 안에서 사용할 수 있게 해 줄 수 있다.
- 구조 분해 할당 시 관용적으로 [state, setState]와 같이 이름 붙여 사용한다.
state 불변성
불변성(immutable)은 "변하지 않는 성질"이다. 프로그래밍에서 불변성을 지킨다는 것은, 메모리 영역의 값을 직접적으로 변경하지 않는다는 것을 의미한다.
setState() -> 컴포넌트 re-rendering
setState는 state는 실행하기 전상태 (이전의 state상태와) 이후 상태를 비교해보고 값이 다르면 re-rendering 하고, 값이 같으면 re-rendering 이 일어나지 않는다. 하지만, 불변성을 지키지 않고 메모리 영역의 값을 직접 변경하면 리액트는 state가 바뀌었다고 인지하지 못한다. 리액트는 이전 state와 이후 state를 비교할 때, 얕은 비교(Shallow Compare)를 하기 때문이다.
💡원시 타입 state 다루기
const [count, setCount] = useState(0);
const [show, setShow] = useState(true);
const [operator, setOperator] = useState(operators[0]);
원시 타입(boolean, number, string)은 불변성을 가지고 있다. 변수에 원시 타입의 값을 할당하면, 메모리에 값 자체가 저장된다.
return (
<div>
<button onClick={() => {
let result;
if (operator === "+") result = count + 1;
if (operator === "-") result = count - 1;
if (operator === "*") result = count * 1;
setCount(result);
}}>
{operator}1
</button>
<button onClick={() => setShow(!show)}>Show and Hide</button>
<button
onClick={() => {
const idx = Math.floor(Math.random() * operator.length);
setOperator(operators[idx]);
}}
>
Change Operator
</button>
<br />
{show && `Counter: ${count}`}
</div>
);
💡참조 타입 state 다루기
const [info, setInfo] = useState({
count: 0,
show: true,
operator: operators[0],
});
참조 타입(object)은 메모리 값이 담긴 주소가 저장된다. 아래와 같이 스프레드 연산자를 이용해서 불변성을 가지도록 호출을 해주면, 리액트는 새로운 객체 데이터가 바뀌었다고 인지하게 되고 새롭게 렌더링을 해준다.
return (
<div>
<button
onClick={() => {
let result;
if (info.operator === "+") result = info.count + 1;
if (info.operator === "-") result = info.count - 1;
if (info.operator === "*") result = info.count * 1;
setInfo({ ...info, count: result });
}}
>
{info.operator}1
</button>
<button
onClick={() => {
setInfo({ ...info, show: !info.show });
}}
>
Show and Hide
</button>
<button
onClick={() => {
const idx = Math.floor(Math.random() * operators.length);
setInfo({ ...info, operator: operators[idx] });
}}
>
Change Operator
</button>
<br />
{info.show && `Counter: ${info.count}`}
</div>
);
props와 state비교
props (properties)와 state는 일반 JavaScript 객체이다. 두 객체 모두 렌더링 결과물에 영향을 주는 정보를 갖고 있는데, 한 가지 중요한 방식에서 차이가 있다. props는 (함수 매개변수처럼) 컴포넌트에 전달되는 반면 state는 (함수 내에 선언된 변수처럼) 컴포넌트 안에서 관리된다.
'Dev > React' 카테고리의 다른 글
[React] useCallback으로 useEffect 심화 활용 (0) | 2022.12.15 |
---|---|
[React] useEffect hook 쉽게 알아보기 (0) | 2022.12.15 |
[React] key가 필요한 이유와 주의할 점 (0) | 2022.12.10 |
댓글