
데이통 통신에는
fetch랑 axios 두개이다..
웹브라우저에서 데이터 통신을 하기위한 도구
fetch -> 웹브라우저가 제공
비동기로 동작합니다
1 Promise then 방시긍로 동작하는 방식
1-1. pending (대기) fulfiled 이행(성공적으로 수행햇다) , rejected(거절, 실패했다)
fetch는 Promise 객체를 반환한다 fetch의 then catch가 있다
근데 로딩이 느려서 깜빢임이 길때를 생각해서 로딩처리를 해주는거
이제부터 하는건 옵션 아래 코드가 기본 디폴트 값 ㅇㅇ 여기에 로딩처리, 에러처리 해주는거
const FetchData = () => {
const [data, setData] = useState(null);
useEffect(()=>{
//왜 json이 response 객체에 없는데 어케 쓰냐 그 response객체가
//가지고 있는 내재적잠재적인 포로토타입 객체에 json이 있다
//json은 또 promise를 반환하니까 또 한버 then을 써야 원하는 data를 바들수 있따
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response)=> response.json())//
.then((data)=> setData(data));
}, [])
return (
<>
<div>FetchData Component</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}
지금부턴 옵션!!
로딩 처리, 에러 처리 한거
import { useEffect, useState } from 'react';
const FetchData = () => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [IsError, setIsError] = useState(false);
const [error, setError] = useState(null);
useEffect(()=>{
setIsLoading(true);
setIsError(false);
//왜 json이 response 객체에 없는데 어케 쓰냐 그 response객체가
//가지고 있는 내재적잠재적인 포로토타입 객체에 json이 있다
//json은 또 promise를 반환하니까 또 한버 then을 써야 원하는 data를 바들수 있따
fetch("https://jsonplaceholder.typicode.com/posts2")
.then((response)=> {
if(response.ok){
response.json()
}
throw new Error("데이터를 불러오는데 실패");
})
.then((data)=> setData(data))
.catch((error)=>{
setError(error.message);
setIsError(true)
})
.finally(()=>setIsLoading(false))
}, [])
if(isLoading) {
return <h1>Loading..</h1>
}
if(IsError) {
return <h1>Error..{error}</h1>
}
return (
<>
<div>FetchData Component</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}
export default FetchData;
signal추가
import { useEffect, useState } from 'react';
const FetchData = () => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [IsError, setIsError] = useState(false);
const [error, setError] = useState(null);
useEffect(()=>{
setIsLoading(true);
setIsError(false);
const controller = new AbortController()
const signal = controller.signal;
//왜 json이 response 객체에 없는데 어케 쓰냐 그 response객체가
//가지고 있는 내재적잠재적인 포로토타입 객체에 json이 있다
//json은 또 promise를 반환하니까 또 한버 then을 써야 원하는 data를 바들수 있따
fetch("https://jsonplaceholder.typicode.com/posts",{signal})
.then((response)=> {
if(response.ok){
response.json()
}
throw new Error("데이터를 불러오는데 실패");
})
.then((data)=> setData(data))
.catch((error)=>{
setError(error.message);
setIsError(true)
})
.finally(()=>setIsLoading(false))
return () => {
controller.abort();
};
}, [])
if(isLoading) {
return <h1>Loading..</h1>
}
if(IsError) {
return <h1>Error..{error}</h1>
}
return (
<>
<div>FetchData Component</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}
export default FetchData;
2. async await (Promise then보다 후에 나왓음 좀더 간단함)
import { useEffect, useState } from 'react';
const FetchData = () => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [IsError, setIsError] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(()=>{
const controller = new AbortController()
const signal = controller.signal;
//왜 json이 response 객체에 없는데 어케 쓰냐 그 response객체가
//가지고 있는 내재적잠재적인 포로토타입 객체에 json이 있다
//json은 또 promise를 반환하니까 또 한버 then을 써야 원하는 data를 바들수 있따
const fetchData = async() => {
setIsLoading(true);
setIsError(false);
setError(null);
try{
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts",
{
signal
}
)
if(!response.ok){
throw new Error('데이터를 불러오는데 실패');
}
const data = await response.json()
setData(data);
} catch(error){
if(error instanceof Error && error.name === "AbortError") return;
setError(error instanceof Error ? error.message : 'unknown error')
setIsError(true)
}finally{
if(!signal.aborted){
setIsLoading(false)
}
}
}
// .then((response)=> {
// if(response.ok){
// response.json()
// }
// throw new Error("데이터를 불러오는데 실패");
// })
// .then((data)=> setData(data))
// .catch((error)=>{
// if(error.name === "AbortError") return;
// setError(error.message);
// setIsError(true)
// })
// .finally(()=>{
// if(!signal.aborted){
// setIsLoading(false)
// }
// })
// return () => {
// controller.abort();
// };
}, [])
if(isLoading) {
return <h1>Loading..</h1>
}
if(IsError) {
return <h1>Error..{error}</h1>
}
return (
<>
<div>FetchData Component</div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</>
)
}
export default FetchData;
axios -> 라이브러리이기에 더 많은 기능을 제공하긴 한다
이렇게 하면 이미지 경로를 오토임폴드하게 해줌

error boundary 런타임 중에 발생하는 오류를 잡기 위한 것
react router
npm install react-router-dom
하고
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import { RouterProvider } from 'react-router-dom'
import { router } from './router/index.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<RouterProvider router={router}/>
</StrictMode>,
)
import { createBrowserRouter } from 'react-router-dom';
import HomeView from '../views/HomeView';
import AboutView from '../views/AboutView';
import BlogView from '../views/BlogView';
export const router = createBrowserRouter([
{
path: "/",
element: <HomeView/>
},
{
path: "/about",
element: <AboutView/>
},
{
path: "/blog/:id",
element: <BlogView/>
}
]);
url 끝에 잇는 변수 사용가능
import { parsePath, useParams } from 'react-router-dom';
const BlogView = () => {
const params = useParams();
console.log(params);
return (
<>
<div>BlogView Component</div>
</>
)
}
export default BlogView;

디폴트레이아웃 만들어놓고
import { Outlet } from 'react-router-dom';
const DefaultLayout = () => {
return (
<>
<header>
<h1>header area</h1>
</header>
<main>
<h1>main area</h1>
<Outlet/>
</main>
<footer>
<h1>footer area</h1>
</footer>
</>
)
}
export default DefaultLayout;
import { createBrowserRouter } from 'react-router-dom';
import HomeView from '../views/HomeView';
import AboutView from '../views/AboutView';
import BlogView from '../views/BlogView';
import DefaultLayout from '../layouts/DefaultLayout';
import BlogLayout from '../layouts/BlogLayout';
export const router = createBrowserRouter([
{
path: "/",
element: <DefaultLayout/>,
children: [{
path: '/',
element: <HomeView/>
}]
},
{
path: "/about",
element: <AboutView/>
},
{
element: <BlogLayout/>,
children: [{
path: "/blog/:blogId",
element: <BlogView/>
}
]
}
]);
json이라는 가상의 서버?
thunder 라는extension 사용법
// https://localhost:3000/posts?필드명_ne=값
// https://localhost:3000/posts?필드명_like=값
// [GET] https://localhost:3000/posts -> posts 속성의 데이터 전체 가져오기
// [GET] https://localhost:3000/posts/1 -> posts 속성의 데이터 중 id가 1인 것만 가져오기
// [POST] https://localhost:3000/posts -> posts 속성에 JSON 객체로 넘긴 데이터 추가하기
// [DELETE] https://localhost:3000/posts/1 -> posts 속성의 데이터 중 id가 1인 것 삭제
// [PUT/전체] https://localhost:3000/posts/1 -> posts 속성의 데이터 중 id가 1인 것의 데이터 변경
// [PATCH/일부분] https://localhost:3000/posts/1 -> posts 속성의 데이터 중 id가 1인 것의 데이터 변경
그리고 상태관리는 zustand를 씀..
—————————————————————
본 후기는 본 후기는 [유데미x스나이퍼팩토리] 프로젝트 캠프 : React 2기 과정(B-log) 리뷰로 작성 되었습니다. #유데미 #udemy #웅진씽크빅 #스나이퍼팩토리 #인사이드아웃 #미래내일일경험 #프로젝트캠프 #부트캠프 #React #리액트프로젝트 #프론트엔드개발자양성과정 #개발자교육과정