[유데미x스나이퍼팩토리] 프로젝트 캠프 Next.js 1기 9일차

oweaj·2024년 6월 5일
0
post-thumbnail

Fetch

1) Fetch

  • Fetch API는 브라우저에 내장되어 있는 네트워크 요청을 위한 API이며 기본적으로 Promise를 반환하고 비동기로 네트워크 요청을 보낼 수 있다.
  • 요청에 대한 응답으로 Response 객체를 반환하고 이 객체는 Promise를 반환하기 때문에 then을 이용해 응답을 처리한다.
  • then은 콜백 함수를 사용하므로 코드가 콜백 지옥에 빠질 수 있다.
const fetchData = () => {
  fetch(url)
    .then((response) => response.json())
    .then((data) => {
      console.log(data);
    })
    .catch((error) => {
      console.log(error);
    });
};

2) async / await

  • async 함수 내에서 await 키워드를 사용해 비동기 작업을 하고 해당 작업이 완료될 때까지 기다린 후 결과를 반환한다.
  • then에 비해 await 키워드는 간결하고 코드를 더 선언적으로 만들어 주며 비동기 작업을 순차적으로 처리할 수 있다.
const fetchDataAsync = async () => {
  try {
    const response = await fetch(url);
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.log(error);
  }
};

3) axios

  • Axios는 내장 Fetch API보다 좀 더 강력하고 사용하기 쉬운 HTTP 클라이언트 라이브러리로써 이를 통해 비동기 작업을 보다 쉽게 처리할 수 있다.

  • 서버로부터 받은 JSON 형식의 응답을 자동으로 JavaScript 객체로 쉽게 변환한다.

const getHandler = async () => {
    try {
      const response = await axios.get(url);
      console.log(response)
    } catch (error) {
      console.log(error);
    }
  };

3-1) axiosInstance

  • axios 인스턴스 생성하면 서버와의 통신 시 공통으로 필요한 설정을 반복하지 않고 설정한 인스턴스를 재사용할 수 있다.
// axios 인스턴스 생성
export const axiosInstance = axios.create({
  baseURL: 'http://localhost:4000',
  timeout: 1000,
  headers: { 'Content-Type': 'application/json' },
});

---------------------------------------------------

> baseURL : api의 기본 url

> timeout : 요청을 보내고 응답을 받을 때까지 지정된 시간이 초과되면 요청이 자동으로 취소되므로 응답이 오래걸려 사용자가 기다리는 것을 방지함

> headers : 모든 HTTP 요청에 기본적으로 포함될 HTTP 헤더를 정의하며 서버와의 통신에 필요한 공통 헤더를 설정
  • 설정한 인스턴스 활용
const getTodo = async () => {
  try {
    const response = await axiosInstance.get('/todos');
    console.log(response.data);
  } catch (error) {
    console.log(error);
  }
}

zustand

// useStore.ts 
import { create } from 'zustand';

interface ICountType {
  count: number;
  plus: () => void;
  minus: () => void;
}

// store 생성
export const useCountStore = create<ICountType>((set) => ({    // set은 state를 변경하고 새로운 값 설정
  count: 0,
  plus: () => set((state) => ({ count: state.count + 1 })),
  minus: () => set((state) => ({ count: state.count - 1 })),
}));

--------------------------------------------------------------

// App.tsx
import Minus from './components/Minus';
import Plus from './components/Plus';
import { useCountStore } from './store/useStore';  // 생성한 store import

function App() {
  const count = useCountStore((state) => state.count);  // count 상태 가져오기

  return (
    <>
      <h1>Count : {count}</h1>
      <Plus />
      <Minus />
    </>
  );
}

export default App;
  • Plus 컴포넌트
// Plus.tsx
import { useCountStore } from '../store/useStore';

const Plus = () => {

  // 상태를 업데이트하는 함수로 set 매서드를 호출해 상태를 변경함
  const plus = useCountStore((state) => state.plus);  
  
  return <button onClick={plus}>plus</button>;
};

export default Plus;

=> 전역으로 제공되기 때문에 다른 컴포넌트에서도 필요한 state값을 가져올 수 있다.

react router dom

  • BrowserRouter

// main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";

import App from "./App.tsx";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root")!).render(
  <BrowserRouter>  // BrowserRouter로 감싸준다.
    <App />
  </BrowserRouter>
);
import React from 'react';
import { Routes, Route } from 'react-router-dom';

// Routes -> Route를 통해 라우팅을 함

const App = () => {
  return (
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
      </Routes>
  );
};
  • RouterProvider

< React Router 버전 6.4부터 지원 >

// router.tsx
const router = createBrowserRouter([   // createBrowserRouter를 이용해서 라우팅 처리할 라우터 객체를 생성한다. 
  {
    path: '/',
    element: <Home />,
    children: [
      {
        path: '/login',
        element: <Login />,
      },
      {
        path: '/register',
        element: <Register />,
      },
    ],
  },
]);

export default router;
// main.tsx
import { RouterProvider } from 'react-router-dom';
import { router } from './router/router';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <>
	// router RouterProvider의 router props으로 전달해 라우팅을 설정 처리를 할 수 있게 한다.
    <RouterProvider router={router} />
  </>
);

위 router 라우터 객체를 보면 root 경로에 Home컴포넌트와 Login과 Register 2개의 자식 경로를 설정했다.
또한 element를 사용해 아래와 같이 공통적으로 나타나는 요소를 처리 할 수 있다.

{
    element: <DefaultLayout />,
    children: [
      { path: '/', element: <Home /> },
      { path: '/login', element: <Login /> },
      { path: '/register', element: <Register /> },
    ],
  },
// DefaultLayout.tsx

const DefaultLayout = () => {
  return (
    <>
      <Header />
      <Outlet />
      <Footer />
    </>
  );
};

이렇게 하면 children인 Home, Login, Register 컴포넌트들이 outlet을 통해 DefaultLayout 컴포넌트의 구조에 따라 공통된 header와 footer를 보여주게된다.


profile
데굴데굴데굴데굴데굴

0개의 댓글