[다시] React Hooks + TypeScript
2025. 3. 14. 10:46ㆍprogramming/React.js
1. useState와 TypeScript
상태(state)의 타입을 명시
✅ 기본 타입 지정 (string, number, boolean 등)
import { useState } from "react";
function Counter() {
const [count, setCount] = useState<number>(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
✅ 객체 상태 관리 (interface 사용)
interface User {
name: string;
age: number;
}
function UserProfile() {
const [user, setUser] = useState<User | null>(null);
return (
<div>
<button onClick={() => setUser({ name: "John", age: 30 })}>Set User</button>
{user && <p>{user.name} - {user.age}</p>}
</div>
);
}
2. useEffect와 TypeScript
의존성 배열과 함께 사용하면 특정 값이 변경될 때만 실행
import { useState, useEffect } from "react";
function Timer() {
const [count, setCount] = useState<number>(0);
useEffect(() => {
const interval = setInterval(() => {
setCount((prev) => prev + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
return <p>Timer: {count}</p>;
}
3. useContext와 TypeScript
Context API를 사용할 때, createContext에 타입을 지정하여 사용.
import { createContext, useContext } from "react";
interface ThemeContextType {
theme: "light" | "dark";
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextType | null>(null);
export function useTheme() {
const context = useContext(ThemeContext);
if (!context) throw new Error("useTheme must be used within a ThemeProvider");
return context;
}
function ThemedButton() {
const { theme, toggleTheme } = useTheme();
return (
<button onClick={toggleTheme} style={{ background: theme === "dark" ? "#333" : "#fff" }}>
Theme: {theme}
</button>
);
}
4. useReducer와 TypeScript
복잡한 상태 관리 useReducer 사용
import { useReducer } from "react";
interface State {
count: number;
}
type Action = { type: "increment" } | { type: "decrement" };
function reducer(state: State, action: Action): State {
switch (action.type) {
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
<span>{state.count}</span>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
</div>
);
}
5. useRef와 TypeScript
useRef는 DOM 요소를 조작하거나, 상태 유지에 사용
✅ DOM 요소 참조
import { useRef, useEffect } from "react";
function InputFocus() {
const inputRef = useRef<HTMLInputElement | null>(null);
useEffect(() => {
inputRef.current?.focus();
}, []);
return <input ref={inputRef} />;
}
✅ 값 저장 (current를 활용)
import { useRef } from "react";
function Stopwatch() {
const countRef = useRef<number>(0);
function increment() {
countRef.current += 1;
console.log("Count:", countRef.current);
}
return <button onClick={increment}>Increment</button>;
}
6. useCallback과 TypeScript
함수를 메모이제이션하여 불필요한 렌더링을 방지 ( 특정 함수가 불필요하게 다시 생성되는 것을 방지 ), 주로 자식 컴포넌트로 props로 전달되는 함수에 사용됩니다. 예를 들어, 다음과 같은 상황에서 유용. 특히, 자식 컴포넌트가 React.memo로 감싸져 있을 때 효과적
- 의존성 배열 [] 안에 포함된 값들이 변경될 때만 함수가 다시 생성
- 빈 배열 []이라면, 초기 렌더링 시에만 함수가 생성되고 이후에는 재사용된다.
import { useCallback, useState } from "react";
function Button({ onClick }: { onClick: () => void }) {
return <button onClick={onClick}>Click</button>;
}
function Parent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount((prev) => prev + 1);
}, []); //의존성 배열 [] 뎁스
return <Button onClick={handleClick} />;
}
7. useMemo와 TypeScript
연산 비용이 큰 계산으로 인해 발생하는 성능 저하를 줄이는 데 도움을 줍니다.
특정 값(value)을 메모이제이션합니다. -> 연산 결과를 저장하여 불필요한 재계산을 방지하고 싶을 때 사용합니다.
import { useMemo, useState } from "react";
function ExpensiveComponent({ num }: { num: number }) {
const expensiveValue = useMemo(() => {
console.log("Calculating...");
return num ** 2;
}, [num]);
return <p>Result: {expensiveValue}</p>;
}
8. 커스텀 Hook 만들기 (Custom Hook + TypeScript)
import { useState, useEffect } from "react";
function useFetch(url: string): T | null {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then((res) => res.json())
.then((data) => setData(data));
}, [url]);
return data;
}
function App() {
const data = useFetch<{ title: string }>("https://jsonplaceholder.typicode.com/todos/1");
return {JSON.stringify(data, null, 2)};
}
🚀 정리
- useState<T>() → 상태의 타입 지정
- useEffect → 부수 효과 처리
- useContext<T>() → 전역 상태 관리
- useReducer<State, Action>() → 복잡한 상태 관리
- useRef<T>() → DOM 요소 및 값 저장
- useCallback(()=>{},[]), useMemo → 성능 최적화
- 커스텀 Hook → 코드 재사용성 향상
'programming > React.js' 카테고리의 다른 글
[다시] 메모이제이션 Hooks (useMemo Vs useCallback) (0) | 2025.03.14 |
---|---|
러닝리액트 요약 Day1 (0) | 2023.01.07 |
React / TS ] CRA로 프로젝트 생성 시, 절대경로 사용하기 (feat. craco) (0) | 2021.12.16 |
npm run start가 안된다면..!! ( 리액트 웹팩 버전 안 맞을 때 ) (0) | 2021.01.12 |