📍 기본 문법
const [state, setState] = useState(initialValue);
state → 현재 상태 값 (상태 값)setState → 상태를 변경하는 함수 (상태 변경 함수)initialValue → 초기 상태 값 (숫자, 문자열, 배열, 객체 등 가능)📍 예제
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0); // 초기값 0 설정
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
🔮 초기 상태 (0) 을 버튼 클릭 시 1씩 증가된 값으로 바꿔주는 App
import { useState } from "react"; 를 통하여 import 해야 함useState(0) → 초기 값을 0으로 설정onClick={() => setCount(count + 1) 버튼에 onClick 이벤트를 사용하여 클릭 시 count 숫자가 1씩 증가 📍 예제
import { useState } from 'react'
import './App.css'
function App() {
const [text, setText] = useState("안녕하세요!");
const [inputValue, setInputValue] = useState("")
const handleClick = () => {
setText(inputValue);
};
return (
<div>
<h2>{text}</h2>
<input type={text} value={inputValue} onChange={(e) =>
setInputValue(e.target.value)}></input>
<br/>
<button onClick={handleClick}>☄️</button>
</div>
);
}
export default App
🔮 초기 상태 ('안녕하세요!') 를 버튼 클릭 시 input 값에 있는 값으로 바꿔주는 App
handleClick() 함수 생성value={inputValue} : input 값에 들어오는 value 값을 inputValue 상태 값으로 설정onChange={(e) => setInputValue(e.target.value)} : input 값이 변경(change) 되면 이벤트 실행 onClick={handleClick} : 버튼 클릭 시 handleClick() 함수 실행📍 예제
import { useState } from 'react'
import './App.css'
function App() {
const [todos, setTodos] = useState(["할 일 1", "할 일 2"]);
const [inputValue, setInputValue] = useState("");
const addTodo = () => {
if (inputValue.trim() === "") return; // 빈 문자열 방지
setTodos([...todos, `${inputValue}`]);
setInputValue(""); // 빈 공백으로 초기화
};
return (
<>
<div>
<ul>
{todos.map((todo, index) => (
<li key={index}>{todo}</li>
))}
</ul>
<input type='text' value={inputValue}
onChange={(e) => setInputValue(e.target.value)}></input>
<button onClick={addTodo}>할 일 추가</button>
</div>
</>
);
}
export default App
🔮 초기 상태의 할 일 목록에서 버튼 클릭 시 input 값에 있는 값이 할 일 목록에 추가되는 App
useState(["할 일 1", "할 일 2"]) → 배열 상태 초기화setTodos([...todos, `${inputValue}`]) → 기존 배열을 복사하고 새로운 값(inputValue) 추가{todos.map((todo, index) => (<li key={index}>{todo}</li>)) 📍 예제
import { useState } from 'react'
import './App.css'
function App() {
const [user, setUser] = useState({ name: "홍길동", age: 20 });
return (
<div>
<p>이름: {user.name}</p>
<p>나이: {user.age}</p>
<button onClick={() => setUser({ ...user, age: user.age + 1 })}>
나이 증가
</button>
</div>
);
}
export default App
🔮 초기 상태의 객체 name: 홍길동, age: 20에서 버튼 클릭 시 나이만 증가하는 App
useState({ name: "홍길동", age: 25 }) → 객체 상태 초기화setUser({ ...user, age: user.age + 1 }) → 기존 객체를 유지하면서 나이만 변경📍 잘못된 예제 (❌)
import { useState } from 'react'
import './App.css'
const heavyWork = () =>{
console.log('엄청 무거운 작업!!!') ;
return ['홍길동','김민수'];
}
function App() {
const [names, setNames] = useState(heavyWork())
const [input, setInput] = useState("");
const handleInputChange = (e) => {
setInput (e.target.value);
};
const handleUpload = () => {
setNames((prevState) => {
console.log('이전 state: ', prevState);
return[input, ...prevState]
})
}
return (
<div>
<input type="text" value={input} onChange={handleInputChange}/>
<button onClick={handleUpload}>Upload</button>
{names.map( (name, idx) => {
return <p key={idx}>{name}</p>;
})}
</div>
) ;
}
export default App
const [names, setNames] = useState(heavyWork()) : 입력 시 해당 작업이 첫 랜더링, 입력 변경 시 모두 리턴됨 📍 잘못된 예제 수정 코드 (⭕️)
function App() {
const [names, setNames] = useState(() => {
return heavyWork();
})
import { useState } from 'react'
import './App.css'
function App() {
return (
<>
<Hello />
<Hello />
</>
)
}
function Hello (){
const [name, setName] = useState('neul')
return (
<>
<h1>이름 변경 [useState]</h1>
<h2>{name}</h2>
<button onClick={()=> setName(name === 'neul' ? 'reum' : 'neul')}>🔀</button>
</>
)
}
export default App

🔮 한 컴포넌트가 여러개 일 때
⚡️ 상태를 직접 수정하면 안 됨! ( 상태 변경 함수 - setState 사용 필수)
const [count, setCount] = useState(0);
count = count + 1; // ❌ 잘못된 방식
setCount(count + 1); // ✅ 올바른 방식
⚡️ 비동기적으로 동작함 (업데이트가 즉시 반영되지 않음)
setCount(count + 1);
console.log(count); // 이전 값이 출력될 수도 있음
⚡️ 이전 상태를 기반으로 업데이트할 때 최신 상태를 저장해주는 prevState 사용
setCount(prev => prev + 1);
→ 이렇게 하면 count 값이 정확하게 업데이트됨.
원래 React에서 상태를 관리하려면 클래스 컴포넌트를 사용해야 했지만, React 16.8부터 함수형 컴포넌트에서도 상태를 관리할 수 있도록 훅이 도입되었다.
class형 함수를 이용하여 상태를 관리하려면 코드가 길어져 어렵고 복잡했지만 함수형 컴포넌트와 훅을 이용하여 상태를 관리 할 수 있다는 점이 최고의 장점인 것 같다.
이 점을 잘 이용하여 더 간결하고 쉽고 좋은 코드 개발을 할 것이다.