this.state 와 setState 를 대체하는 역할import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0); // useState 사용
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
state 는 현재 상태, setState 는 변경된 상태를 의미한다. (라고 이해했다.)
그래서 state 에 어떤 변동사항을 주고, setState 를 호출해서 초기값을 업데이트해주는 상태 관리 훅이라고 할 수 있다.
<button onClick={() => count + 1}>+1</button> // ❌ 이렇게 하면 안 됨!
<button onClick={() => setCount(count + 1)}>+1</button> // ✅ setState를 사용해야 함!
외 않되?
왜 안되냐면
count 를 직접 변경하면, console 창에서는 변경이 일어나지만, 상태가 업데이트되지 않기 때문에 리렌더링이 일어나지 않기 때문이다. 반드시 setCount() 로 코드에 변동사항이 발생했음을 컴퓨터에게 알려줘,,,
useState 는 불변성을 유지해야 한다. 기존 상태를 직접 수정하는 것이 아니라, 새로운 상태를 만들어서 화면을 업데이트해줘야 한다.
🔗 TIP : 상태를 업데이트할 때에, 이전 상태를 기준으로 해야 하는 경우가 있다. 그런 경우에는 콜백 방식으로 () => setCount(prev => prev + 1) 로 적어 주면, 이전 상태 값을 안전하게 받아 와서 업데이트할 수 있다!
componentDidMount, componentDidUpdate, componentWillUnmount 를 합친 개념import { useEffect, useState } from "react";
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("🟢 매 렌더링마다 실행됨!");
});
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
export default App;
useEffect 는 함수 와 의존성배열 을 가진다. 기본적인 구조는 아래와 같다.
useEffect(() => {
// 함수;
}, // [의존성배열]);
이 로직의 함수 자리에는 실행할 조건이 들어가고, 의존성배열 자리에는 UI를 리렌더링할 조건이 되는 요소가 들어간다. 즉, 그 자리에 들어가는 요소에 변동사항이 있을 때에만 페이지가 리렌더링된다.
useEffect(() => {
console.log(`🟠 count가 변경됨: ${count}`);
}, [count]); // count가 변경될 때만 실행
예를 들어 위의 경우 의존성배열 자리에 있는 count 의 상태에 변동이 있으면 useEffect 안의 내용이 실행된다. 이 의존성배열 자리에는 요소가 여러 개 들어갈 수도 있다. 예를 들어, ToDoList 에서 사용자가 title 과 text 값을 입력했을 때에 ToDoList 에 추가하는 함수를 실행하고 싶다면, Add 함수를 선언해준 다음
useEffect(() => {
addTodo();
}, [title, text]);
이렇게 useEffect 안에 넣어주면 된다.