useState vs useEffect
useState와 useEffect는 React의 함수형 컴포넌트에서 가장 자주 사용하는 Hook 중 하나다.
useState
useState는 컴포넌트의 상태(state)를 저장하고 관리할 수 있도록 해주는 Hook이다.
const [state, setState] = useState(initialValue);
- state: 현재 상태 값
- setState: 상태를 업데이트하는 함수
- initialValue: 초기 상태 값
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>현재 카운트: {count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
);
}
이 예시에서는 count라는 상태를 만들고, 버튼을 누르면 setCount로 상태를 업데이트함.
React에서 useState로 만든 상태는 해당 컴포넌트 내부에만 저장된다.
즉, React가 내부적으로 컴포넌트별로 상태를 관리하는 메모리 공간이 있고, 거기에 저장된다.
- 컴포넌트가 렌더링될 때 React는 useState로 만든 상태 값을 기억해두고 있다가
- 상태가 바뀌면, 그 컴포넌트만 다시 렌더링하면서 새로운 상태 값을 보여준다.
React에서 useState로 만든 상태는 컴포넌트의 인스턴스별로 관리되는 값.
useState로 만든 상태는 그 컴포넌트 안에서만 유효하다. 다른 컴포넌트에서 직접 접근하거나 공유할 수 없다.
function A() {
const [text, setText] = useState("hello");
return <B />;
}
function B() {
// 여기서는 A의 text 상태에 접근할 수 없음 ❌
}
상태를 공유하고 싶으면 상태를 상위 컴포넌트로 올리고(props로 내려주기) 하거나,
전역 상태 관리 도구를 사용해야 한다.
상태 공유 방법 예시1: props로 전달
function Parent() {
const [text, setText] = useState("hello");
return (
<>
<ChildA text={text} />
<ChildB setText={setText} />
</>
);
}
function ChildA({ text }) {
return <p>{text}</p>;
}
function ChildB({ setText }) {
return <button onClick={() => setText("hi!")}>Change</button>;
}
상태 공유 방법 예시 2: 전역 상태 관리 도구 사용
- Context API
- Redux
- Recoil
- Zustand, Jotai, 등
Context API를 사용한 전역 상태 공유 예시
목표: text 상태를 여러 컴포넌트에서 읽고, 업데이트할 수 있게 만들기!
1. Context 만들기 (TextContext.js)
import React, { createContext, useState } from 'react';
// Context 객체 생성
export const TextContext = createContext();
export function TextProvider({ children }) {
const [text, setText] = useState("hello");
return (
<TextContext.Provider value={{ text, setText }}>
{children}
</TextContext.Provider>
);
}
2. App.js에서 Provider로 감싸기
import React from 'react';
import { TextProvider } from './TextContext';
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
function App() {
return (
<TextProvider>
<ComponentA />
<ComponentB />
</TextProvider>
);
}
export default App;
3. ComponentA.js – 전역 상태 사용 (읽기)
import React, { useContext } from 'react';
import { TextContext } from './TextContext';
function ComponentA() {
const { text } = useContext(TextContext);
return <p>ComponentA sees: {text}</p>;
}
export default ComponentA;
4. ComponentB.js – 전역 상태 사용 (업데이트)
import React, { useContext } from 'react';
import { TextContext } from './TextContext';
function ComponentB() {
const { setText } = useContext(TextContext);
return (
<button onClick={() => setText("world!")}>
Change Text
</button>
);
}
export default ComponentB;
결과
- ComponentA는 text 상태를 읽기만 하고,
- ComponentB는 text 상태를 변경한다.
- 두 컴포넌트가 서로 전혀 몰라도 같은 상태를 공유할 수 있다.
useEffect
useEffect는 컴포넌트가 렌더링될 때 부수 효과(side effect)를 수행할 수 있도록 해주는 Hook이다. 라이프사이클과 관여되있다.
예를 들면:
- 데이터 불러오기 (fetch)
- 이벤트 리스너 등록/제거
- 타이머 설정
- DOM 조작 등
useEffect(() => {
// 실행할 코드
return () => {
// (선택) 정리(clean-up)할 코드
};
}, [dependency]);
- dependency: 이 배열에 있는 값이 바뀔 때만 effect가 다시 실행됨
- 빈 배열 []: 처음 마운트될 때 한 번만 실행
import React, { useState, useEffect } from 'react';
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(prev => prev + 1);
}, 1000);
// 컴포넌트가 언마운트 될 때 타이머 정리
return () => clearInterval(timer);
}, []);
return <p>초: {count}</p>;
}
이 예시에서는 useEffect로 타이머를 만들고, 컴포넌트가 사라질 때 clearInterval로 정리하고 있다.
Hook | 역할 |
useState | 상태 저장 및 변경 |
useEffect | 컴포넌트 렌더링 후 실행되는 부수효과 처리 |
'프론트엔드 > React' 카테고리의 다른 글
react-share 소셜 미디어 공유 버튼 라이브러리 (0) | 2025.04.13 |
---|---|
Ant Design (0) | 2025.04.12 |
객체의 불변성 (0) | 2025.04.12 |
useParams vs useNavigate (1) | 2025.04.06 |
React 스타일링 방식 비교 (CSS Modules, styled-components, 일반 CSS) (0) | 2025.04.05 |