우선 axios 라이브러리를 설치해야 한다.
import React, { useEffect, useState } from "react";
import axios from "axios";
const App = () => {
const [data, setData] = useState([]); // 데이터 상태
const [loading, setLoading] = useState(false); // 로딩 상태
const [error, setError] = useState(null); // 에러 상태
useEffect(() => {
const fetchData = async () => {
setLoading(true); // 로딩 시작
setError(null); // 이전 에러 초기화
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
);
setData(response.data); // 데이터 저장
} catch (err) {
setError(err.message); // 에러 저장
} finally {
setLoading(false); // 로딩 끝
}
};
fetchData();
}, []); // 컴포넌트 마운트 시 1회 실행
if (loading) return <p>Loading...</p>; // 로딩 중 표시
if (error) return <p>Error: {error}</p>; // 에러 표시
return (
<div>
<h1>Data</h1>
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
</div>
);
};
export default App;


axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'New Post',
body: 'This is the content of the post',
userId: 1,
});
axios.get('https://jsonplaceholder.typicode.com/posts', {
params: { userId: 1 },
});
try {
const response = await axios.get(url);
} catch (err) {
if (axios.isAxiosError(err)) {
console.error('Axios error:', err.message);
} else {
console.error('Unknown error:', err);
}
}
📍 NavLink
React 또는 다른 프론트엔드 프레임워크에서 사용되는 네비게이션 컴포넌트로 사용자는 애플리케이션 내에서 라우트를 이동하며 네비게이션 링크의 활성 상태(active state)를 관리할 수 있다.
- React Router에서 제공하는 컴포넌트로, 네비게이션 링크를 생성할 때 사용됨.
- 특정 경로가 활성화되었을 때(현재 경로와 링크 경로가 일치할 때) 자동으로 CSS 클래스나 스타일을 적용할 수 있음.
- NavLink는 현재 경로와 매칭되면 기본적으로 active라는 클래스를 적용함. 이를 통해 활성화된 링크를 시각적으로 구분할 수 있음.
- className 또는 style 속성에 콜백 함수를 전달하여 동적으로 스타일을 지정할 수 있음.
- NavLink 주요 속성으로는 to, className, style, end, children이 있다.
📍 NavLink 사용법
React Router 라이브러리의 일부로 NavLink를 사용하려면 React Router를 설치해야 함.npm install react-router-dom
✅ NavLink 주요 속성
✔ to ⇒ 이동할 경로를 설정
<NavLink to="/home">Home</NavLink>
✔ className ⇒ 활성화 상태에 따라 동적으로 클래스를 적용
<NavLink
to="/about"
className={({ isActive }) => (isActive ? "active-link" : "inactive-link")}
>
About
</NavLink>
✔ style ⇒ 활성화 상태에 따라 동적으로 인라인 스타일을 지정
<NavLink
to="/contact"
style={({ isActive }) => ({ color: isActive ? "red" : "blue" })}
>
Contact
</NavLink>
✔ end ⇒ 경로가 정확히 일치할 때만 활성화 상태로 간주
<NavLink to="/home" end>
Home
</NavLink>
✔ children ⇒ 링크 내부에 렌더링할 콘텐츠를 설정(텍스트, 아이콘 등을 포함할 수 있음)
예제
먼저 React Router를 사용하기 위해서는 React 버전 16.8 이상이어야 하고 라이브러리 설치 후, 애플리케이션의 루트 컴포넌트를 BrowserRouter로 감싸야 함.
// 기본 설정 예제
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
NavLink를 사용한 예제
import React from 'react';
import { NavLink } from 'react-router-dom';
function Navigation() {
return (
<nav>
<NavLink to="/" end>Home</NavLink>
<NavLink to="/about">About</NavLink>
<NavLink to="/contact">Contact</NavLink>
</nav>
);
}
export default Navigation;
import React from 'react';
import { BrowserRouter as Router, Routes, Route, NavLink } from 'react-router-dom';
function App() {
return (
<Router>
<nav>
<NavLink
to="/"
className={({ isActive }) => (isActive ? "active-link" : "")}
style={({ isActive }) => ({ fontWeight: isActive ? "bold" : "normal" })}
end
>
Home
</NavLink>
<NavLink to="/about">About</NavLink>
<NavLink to="/contact">Contact</NavLink>
</nav>
<Routes>
<Route path="/" element={<h1>Home Page</h1>} />
<Route path="/about" element={<h1>About Page</h1>} />
<Route path="/contact" element={<h1>Contact Page</h1>} />
</Routes>
</Router>
);
}
export default App;
📍 usePromise
React에서 비동기 작업(특히 Promise) 커스텀 훅
- 비동기 로직(예: API 호출, 데이터 처리)을 컴포넌트에 직접 작성하면 코드가 복잡해질 수 있는데, usePromise를 사용하면 보다 깔끔하게 처리하고, 상태 관리(로딩, 성공, 실패)가 용이하게 가능해짐.
usePromise 커스텀 훅을 만드는 예제
import { useState, useEffect } from 'react';
function usePromise(promiseFn, deps = []) {
const [data, setData] = useState(null); // 데이터를 저장
const [isLoading, setIsLoading] = useState(true); // 로딩 상태
const [error, setError] = useState(null); // 에러 상태
useEffect(() => {
setIsLoading(true); // 요청 시작 시 로딩 상태 설정
setError(null); // 에러 초기화
promiseFn()
.then((response) => {
setData(response); // 성공적으로 데이터를 받으면 상태에 저장
setIsLoading(false); // 로딩 끝
})
.catch((err) => {
setError(err); // 에러 발생 시 에러 상태에 저장
setIsLoading(false); // 로딩 끝
});
}, deps); // 의존성 배열에 따라 리렌더링
return { data, isLoading, error };
}
✔ promiseFn
Promise를 반환하는 함수
✔ deps
useEffect의 의존성 배열로, 이 값이 변경될 때마다 다시 promiseFn을 실행
✔ data
성공적으로 데이터를 받았을 때 저장되는 상태
✔ isLoading
데이터 로딩 중에는 true, 완료되면 false로 변경됨
✔ error
요청이 실패했을 때 발생한 에러를 저장하는 상태
import React, { useState } from 'react';
import usePromise from './usePromise';
// 예시 API 호출 함수 (Promise 반환)
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Fetched Data!"); // 성공적으로 데이터 받기
// reject("Error!"); // 에러를 발생시키려면 주석을 풀기
}, 2000);
});
}
function App() {
const { data, isLoading, error } = usePromise(fetchData, []); // usePromise 호출
if (isLoading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
return (
<div>
<h1>{data}</h1> {/* 데이터가 성공적으로 로드되면 화면에 표시 */}
</div>
);
}
export default App;
✔ fetchData 함수
Promise를 반환하는 비동기 작업으로 데이터가 로드되면 "Fetched Data!"가 반환됨.
✔ usePromise(fetchData, [])
fetchData를 호출하고, 결과를 data, isLoading, error로 관리함.
로딩 중에는 "Loading..." 메시지를 표시하고, 에러가 있으면 에러 메시지를, 데이터가 있으면 그 데이터를 화면에 출력함.