컴포넌트 내부에서 바뀔 수 있는 값
State가 변경되어야 리렌더링이 된다.
즉, state를 사용하는 이유는 변경한 데이터를 UI에 반영하기 위한 것이다.
(1) import
import React, { useState } from 'react';
(2) useState 사용 방법
const [ value, setValue ] = useState( 초기값 )
function App() {
//hook
const [state, setState] = useState('initial Value');
const [count, setCount] = useState(0);
const [todoList, setTodoList] = useState([])
return <div>{state}</div>
}
function App() {
const [fruit, setFruit] = useState("포도");
return (
<div>
{fruit}
<br />
<button onClick={() => setFruit("오렌지")}>click</button>
</div>
);
}
function App() {
const [fruit, setFruit] = useState("");
return (
<div>
과일 :{" "}
<input value={fruit} onChange={(event) => setFruit(event.target.value)} />
<br />
{fruit}
</div>
);
}
function App() {
const [id, setId] = useState("");
const [password, setPassword] = useState("");
return (
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignContent: "center",
}}>
아이디:{" "}
<input
type="text"
value={id}
onChange={(event) => setId(event.target.value)}
/>
비밀번호:{" "}
<input
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
/>
<button
onClick={function () {
alert(
`고객님이 입력하신 아이디는 ${id} 이며, 비밀번호는 ${password}입니다.}`
);
}}>
로그인
</button>
</div>
);
}
function App() {
const [count, setCount] = useState(0);
return (
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
height: "100vh",
}}>
{count}
<div>
<button onClick={() => setCount(count + 1)}>+ 1</button>
<button onClick={() => setCount(count - 1)}>- 1</button>
</div>
</div>
);
}
메모리에 있는 값을 변경할 수 없는 특성
원시 데이터는 불변성이 없고
참조형 데이터(객체, 배열, 함수)는 불변성을 가진다.
참조형 데이터에 값을 할당하면 메모리 주소를 받아오고 메모리 주소 위치에 데이터가 저장된다.
위와 같은 점 때문에 원시 데이터처럼 불변성을 갖지 않을 경우를 제외하고
객체, 배열, 함수... 등의 참조형 데이터를 사용할 때는 메모리 주소 위치의 객체 안의 데이터가 변경되기 때문에 메모리 주소 자체는 변경되지 않아 리액트의 입장에선 state가 변경되지 않았다고 인식하여 리렌더링 되지 않는다.
-> 이러한 문제를 해결하기 위해 새로운 객체를 만들어줘야 한다!
새로운 객체를 만드는 방법
spread operator, map(), filter() 같이 새로운 객체 또는 배열을 반환해주는 문법 또는 별도의 패키지를 사용해서 해결할 수 있다.
새로운 객체 및 배열로 대입하면 메모리 주소가 바뀌기 때문에 state가 변경되는 것으로 인식되어 리렌더링된다!
function App() {
const [cats, setCats] = useState(["러시안블루"]);
// 매개변수를 복사한 값을 변경하는 순수함수
function onClickHandler() {
// spread operator 사용하여 복사 -> 새로운 배열 생성 -> state 변경 -> 렌더링
setCats([...cats, "페르시안"]);
}
return (
<div>
{cats}
<button onClick={onClickHandler}>버튼</button>
</div>
);
}
컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업을 의미한다.
순서 : state update -> triggering -> rendering -> commit
오늘은 state의 사용방법과 React에서 setState를 통해 state를 변경해야 하는 이유를 알아보았다.
state란 컴포넌트 내부에서 바뀔 수 있는 값이며 useState()를 import하여 사용할 수 있다. state가 변경되어야 리렌더링이 일어나 바뀐 값으로 화면에 반영할 수 있기 때문에 setState를 꼭 사용해서 state 값을 변경하고 반영해주어야 한다!
원시 데이터가 아닌 참조형 데이터를 사용할 경우 불변성 때문에 바로 setState를 해도 메모리 주소가 변경되지 않고 객체 안의 데이터가 변경되기 때문에 리액트 입장에서는 state의 변경을 인식하지 못한다. 이 경우 렌더링이 되지 않는 문제가 발생한다. 그렇기 때문에 참조형 데이터를 사용할 때는 새로운 객체를 만드는 여러 방법을 사용해서 메모리의 주소를 변경할 수 있도록 만들어줘야 한다.