React Hooks
Hooks 는 리액트 v16.8 에 새로 도입된 기능으로서, 기존의 함수형 컴포넌트에서 할 수 없었던 다양한 작업을 할 수 있게 해줍니다.
함수형 컴포넌트에서 상태(state)와 생명주기(lifecycle) 메서드를 사용할 수 있도록 하는 기능입니다.
코드를 더 간결하고 가독성 있게 작성할 수 있습니다.
*함수형 컴포넌트, 클래스형 컴포넌트
종류
useState
- 상태를 추가하고 관리하는 Hook.
- useState를 사용하여 상태를 선언하면 React는 해당 상태를 관리하고 상태가 변경될 때마다 컴포넌트를 자동으로 리렌더링합니다.
import React, { useState } from 'react';
function Counter() {
// count 상태와 count를 업데이트하는 setCount 함수를 선언합니다.
// 0을 초기값으로 설정
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
{/* 버튼 클릭 시 count를 1씩 증가시키는 함수를 호출합니다. */}
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Counter;
useEffect
- React 컴포넌트의 생명주기 메서드를 함수형 컴포넌트에서 사용할 수 있도록 해주는 Hook.
- 컴포넌트가 렌더링/마운트/업데이트/언마운트될 때 등의 시점에서 특정 작업을 수행.
- useEffect 함수는 두 개의 인자를 받습니다. 첫 번째 인자는 특정 작업을 수행하는 함수이고, 두 번째 인자는 의존성 배열(dependency array)입니다. 의존성 배열에 포함된 값들이 변경될 때마다 첫 번째 인자 함수가 실행됩니다.
- useEffect를 사용하여 비동기 작업을 수행하거나, 외부 데이터를 불러오는 등의 작업을 수행할 수 있습니다.
import React, { useState, useEffect } from 'react';
function Timer() {
// time 상태와 time을 업데이트하는 setTime 함수를 선언합니다.
const [time, setTime] = useState(0);
// 컴포넌트가 렌더링될 때마다 time을 1초마다 업데이트합니다.
useEffect(() => {
const timerId = setInterval(() => {
setTime(prevTime => prevTime + 1);
}, 1000);
// 컴포넌트가 언마운트될 때 타이머를 정리합니다.
return () => clearInterval(timerId);
}, []);
return (
<div>
<p>Time: {time} seconds</p>
</div>
);
}
export default Timer;
import React, { useState, useEffect } from 'react';
function Timer() {
// time 상태와 time을 업데이트하는 setTime 함수를 선언합니다.
const [time, setTime] = useState(0);
const [isRunning, setIsRunning] = useState(true);
// 컴포넌트가 렌더링될 때마다 time을 1초마다 업데이트합니다.
useEffect(() => {
// 타이머가 실행되는 조건을 추가합니다.
if (isRunning) {
const timerId = setInterval(() => {
setTime(prevTime => prevTime + 1);
}, 1000);
// 컴포넌트가 언마운트될 때 타이머를 정리합니다.
return () => clearInterval(timerId);
}
}, [isRunning]); // isRunning 값이 변경될 때만 useEffect가 실행됩니다.
const handleToggle = () => {
setIsRunning(prevIsRunning => !prevIsRunning);
};
return (
<div>
<p>Time: {time} seconds</p>
<button onClick={handleToggle}>{isRunning ? 'Pause' : 'Resume'}</button>
</div>
);
}
export default Timer;
useContext
부모 컴포넌트에서 전역적으로 상태를 공유할 수 있도록 해주는 훅입니다.
import React, { useContext } from 'react';
// Context 생성
const ThemeContext = React.createContext('light');
// 컴포넌트 정의
function ThemeButton() {
const theme = useContext(ThemeContext);
return <button style={{ background: theme }}>Themed Button</button>;
}
// 사용 예시
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemeButton />
</ThemeContext.Provider>
);
}
useReducer
복잡한 상태 관리를 위해 사용되는 훅으로, useState와 비슷하지만 보다 복잡한 로직을 다룰 수 있습니다.
import React, { useReducer } from 'react';
// 리듀서 함수
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
case 'decrement':
return { count: state.count - 1 };
default:
throw new Error();
}
}
// 컴포넌트 정의
function Counter() {
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: 'increment' })}>+</button>
<button onClick={() => dispatch({ type: 'decrement' })}>-</button>
</div>
);
}
useCallback
메모이제이션된 콜백 함수를 생성하는 훅으로, 불필요한 렌더링을 방지할 수 있습니다.
import React, { useState, useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);
return (
<div>
Count: {count}
<button onClick={increment}>Increment</button>
</div>
);
}
Custom Hook
React에서 자주 사용되는 로직을 재사용 가능한 함수로 추상화하여 컴포넌트 간에 공유할 수 있도록 하는 방법입니다.
1. 훅을 만들 함수 정의
커스텀 훅은 필요한 로직을 포함하는 함수로, 함수명이 use로 시작해야 합니다.
예시) URL에서 데이터를 가져오는 로직
import { useState, useEffect } from 'react';
// API를 호출하여 데이터를 가져오는 커스텀 훅
const useFetchData = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const json = await response.json();
setData(json);
setLoading(false);
} catch (error) {
setError(error);
setLoading(false);
}
};
fetchData();
// 컴포넌트가 언마운트될 때 정리
return () => {
// 실행 취소 및 정리 작업
};
}, [url]);
return { data, loading, error };
};
export default useFetchData;
2. 훅을 사용할 컴포넌트에 적용
예시) useFetchData 커스텀 훅을 사용하여 데이터를 가져와서 로딩 상태에 따라 다른 컴포넌트를 렌더링하고 있습니다.
import React from 'react';
import useFetchData from './useFetchData';
function MyComponent() {
const { data, loading, error } = useFetchData('https://api.example.com/data');
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error.message}</div>;
}
return (
<div>
{data && (
<ul>
{data.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</div>
);
}
export default MyComponent;
'Frontend > react' 카테고리의 다른 글
socket.io (react) (0) | 2024.02.24 |
---|---|
Redux 설치 및 사용법 (0) | 2023.09.27 |
combineReducers (0) | 2023.09.27 |
react-router-dom 버전6 변경 사항 (0) | 2023.09.25 |
React Router Dom 설정(버전 5.x, 6링크) (0) | 2023.09.25 |