관리 메뉴

CASSIE'S BLOG

슈퍼코딩 복습 75강 본문

PROGRAMMING/React

슈퍼코딩 복습 75강

ITSCASSIE1107 2023. 10. 1. 22:42

 

 

70강~74강

Redux Part 5.

리덕스 비동기 처리를 하는 방법은 두 가지가 있다.
1. 컴포넌트 내의 useEffect() 같은 훅을 통해서
2. Thunk 같은 action creater를 통해서


비동기 로직을 작업하다가 이슈가 생기면 요청을 보내야할 때 보내지 않았거나, 
보내지 않아야할 때 보냈는지 체크해 본다.

 

React Router

 

리액트에서 라우팅을 기존의 전통적인 앱 어플리케이션과 어떤점을 다른점을 가지고
처리를 하는지 알아보자.

 

 

웹브라우저에서 라우팅이란?

(Multi Page Application)에서 페이지가 이동하는 것

/home 
home.html 

-> 페이지 변경

/user
user.html

 

SPA: 싱글 페이지 어플리케이션

여러분들이 만든 서비스에서 여러가지 페이지가 있잖아요
그때마다 새로운 HTML를 불러오는게 아니라
그럴 때 경로만 지정해주고
그 경로에 해당하는 컴포넌트 영역을 보여준다. 

 

 

리액트에서 라우팅을 사용할 수 있는 라이브러리인 
react-router-dom

리액트에서 라우팅을 쓰기 위해 사용하는 라이브러리
client side routing을 가능하게 한다.

 

리액트 라이브러리 공식문서

 

https://reactrouter.com/en/main

 

Home v6.16.0

I'm on v5 The migration guide will help you migrate incrementally and keep shipping along the way. Or, do it all in one yolo commit! Either way, we've got you covered to start using the new features right away.

reactrouter.com

 

클라이언트 측 라우팅을 사용하면 앱이 서버에서 다른 문서를 다시 요청하지 않고도 링크 클릭에서 URL을 업데이트할 수 있습니다. 대신, 앱은 새로운 UI를 즉시 렌더링하고 데이터를 요청하여 fetch페이지를 새로운 정보로 업데이트할 수 있습니다.

이를 통해 브라우저가 완전히 새로운 문서를 요청하거나 다음 페이지에 대한 CSS 및 JavaScript 자산을 재평가할 필요가 없기 때문에 더 빠른 사용자 경험이 가능합니다. 또한 애니메이션과 같은 기능을 통해 더욱 역동적인 사용자 경험을 제공합니다.

클라이언트 측 라우팅은 및를 사용하여 Router페이지를 생성하고 연결/제출함으로써 활성화됩니다 .

 

 


import * as React from "react";
import { createRoot } from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
  Route,
  Link,
} from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: (
      <div>
        <h1>Hello World</h1>
        <Link to="about">About Us</Link>
      </div>
    ),
  },
  {
    path: "about",
    element: <div>About</div>,
  },
]);

createRoot(document.getElementById("root")).render(
  <RouterProvider router={router} />
);

 

 

여기서 traditional websites = 멀티 페이지 애플리케이션을 의미함.

 

여기서 document가 html이란다.

Client Side Routing

React Router enables "client side routing".

In traditional websites, the browser requests a document from a web server, downloads and evaluates CSS and JavaScript assets, and renders the HTML sent from the server. When the user clicks a link, it starts the process all over again for a new page.

Client side routing allows your app to update the URL from a link click without making another request for another document from the server. Instead, your app can immediately render some new UI and make data requests with fetch to update the page with new information.

This enables faster user experiences because the browser doesn't need to request an entirely new document or re-evaluate CSS and JavaScript assets for the next page. It also enables more dynamic user experiences with things like animation.

Client side routing is enabled by creating a Router and linking/submitting to pages with Link and <Form>:

 

그 ui에 필요한 데이터만 fetch를 통해서 받아온다고함.

 

그냥 branch 새로파서 App.js에서 다 지우고 시작해보라고하심. 

 

가장 먼저 해야하는게 라이브러리 설치란다.

일단 브랜치 75강이니까 practice/7-5 만들기
react-router-dom 

 

처음부터 다 만들어서 구축 한 다음에

 

To create a production build, use npm run build하라고 해도 쌤은 안하네

바로 npm install react-router-dom 바로 해뿜

 

그 다음 npm run start

 

쌤이 그냥 App.js 다 지우고 이렇게 만들래

 

 

썜은 이렇게 index.js 코드 몇부분 지우고 남김 

깡통에서 다시 시작해도된다고함.

 

 

라우터를 설정하기 위해서는 
App.js라는 파일이 가장 root 파일인데
여기에서 라우터를 설정해야한다.

create browser router라는 api를 가져와야한다.

const router = createBrowserRouter 이렇게 적으면서

자동으로 import 되게 하기

 

import { createBrowserRouter } from "react-router-dom";

const router = createBrowserRouter

function App() {
  return (
    <div>hello world</div>
  );
}

export default App;

 

요약하면, 배열 안에 객체를 전달하는 것은 함수나 라이브러리가 다양한 구성 요소 또는 설정을 처리하고 조작할 수 있도록 하는 일반적인 패턴 중 하나입니다. 이렇게 하면 코드의 유연성과 확장성을 높일 수 있습니다.

 



{} 안에 라우터를 지정해주는거임.
path: root path를 지정해준다.
children 에 하위에 작성하고 싶은 path들을 적어주면 된다고함.

element: root element 지정해주고
만들어줘야한다.
element는 컴포넌트다.

 

import { createBrowserRouter } from "react-router-dom";

const router = createBrowserRouter([{
  path: '/',
  element: <RootElement/>,
  children:[
    {
      path: '/welcome', element: <Welcome/>
    },
    {
      path: '/products', element: <Products/>
    },
  ]

}])

function App() {
  return (
    <div>hello world</div>
  );
}

export default App;

 

<Outlet>은 RootElement에만 들어가는 개념인데
Path별로 컴포넌트를 Element로 넣어주는데
그 Element가 요 RootElement의 Outlet에 들어가서 
<Outlet />을 꼭 만들어줘야한다

 

RootElement.js

 

import React from 'react';
import { Outlet } from 'react-router-dom';

const RootElement = () => {
    return (
        <div>
        <p>Hello Root</p>
        <Outlet/>
           
        </div>
    );
};

export default RootElement;

 

index.js 

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);





App.js

 

import { createBrowserRouter } from "react-router-dom";
import RootElement from "../public/components/RootElement";
import Welcome from "../public/components/Welcome";
import Products from "../public/components/Products";

const router = createBrowserRouter([{
  path: '/',
  element: <RootElement/>,
  children:[
    {
      path: '/welcome', element: <Welcome/>
    },
    {
      path: '/products', element: <Products/>
    },
  ]

}])

function App() {
  return (
    <div>hello world</div>
  );
}

export default App;

Outlet은 RootElement 컴포넌트에만 만드는거다..!

 

Welcome.js

import React from 'react';
import { Outlet } from 'react-router-dom';

const Welcome = () => {
    return (
        <div>
            Hello Welcome
        </div>
    );
};

export default Welcome;

Product.js

import React from 'react';
import { Outlet } from 'react-router-dom';

const Products = () => {
    return (
        <div>
            Welcome Products
        </div>
    );
};

export default Products;

 

createBrowerRounter는 배열로 라우터를 받는데

지금은 배열의 원소가 1개이다.
배열에 Path가 있고
가장 Root 경로에 RootElement가 들어가고
RootElement 에는 Outlet요소가 들어가게되서

그 RootElement하위에 있는 애들은 Outlet에 들어가게되고

App에서 사용할 떄는
React Router에서 제공하는 API인
RouterProvider를 사용합니다.

그리고 router = {router}
우리가 만든 router를 넣어주면 된다고함.

 

 

 

 

src 경로 하위에 component 들어가서 해야함!!! 또 배웠다.

 

App.js

 

import { RouterProvider, createBrowserRouter } from "react-router-dom";
import RootElement from "./components/RootElement";
import Welcome from "./components/Welcome";
import Products from "./components/Products";

const router = createBrowserRouter([{
  path: '/',
  element: <RootElement/>,
  children:[
    {
      path: '/welcome', element: <Welcome/>
    },
    {
      path: '/products', element: <Products/>
    },
  ]

}])

function App() {
  return (
    <RouterProvider router={router}>
    </RouterProvider>
  );
}

export default App;

 

import React from 'react';
import { Outlet } from 'react-router-dom';

const RootElement = () => {
    return (
        <div>
        <p>Hello Root</p>
        <Outlet/>
           
        </div>
    );
};

export default RootElement;

 

Welcome.js랑 Products.js는 위에 코드 올린거랑 똑같다. 

 

<NavLink>라는 리액트 라우터돔에 네비게이션에서 링크를 연결하는
api를 사용해 보도록 할게요.

 

이렇게 만들어주면 /welcome을 하는 NavLink다.

 

만들어만줬지..
지금 아무것도 안했잖아
MainHeader를 사용을 해줘야하잖아
App.js에서 사용하겠데

RootElement로 타고 가서

<p>Hello Root</p>를 지우고

<MainHeader /> 적으면 자동으로 import된다.

 

 

다이나믹 라우팅

아이디값에 따라서 페이지 컴포넌트의 내용이 바뀌는 그러한 라우팅을 
다이나믹 라우팅이라고 한다.

 

useParams() : 
훅인데
리액트 라우터 돔에서 파라미터를 받는 훅이다.

 

Product 컴포넌트 만들고

 

 

 

product가 아이디가 존재하는데
아이디에 따라서 다른 값들을 보여주는 컴포넌트를 만들어보자...! 

 

그 다음 ProductDetail 페이지를 (Product에서 ProductDetail) 이름 바꿈

Products에서 <section> 태그를 만들고
MainHeader에서 <nav>. ..그 태그들 복붙하고

이제는 NavLink가 아닌 그냥 Link
그 다음 Link import

 

 

  <Link to='products/p1'>1번 상품</Link> 이런 식으로 추가하고

그리고, 프로덕트 디테일이라는 컴포넌트를 라우터에서 정의를 해줘야지 쓸 수 있다.

 

:productId가 파라미터가 된다는데
App.js에
path: "/products/:productId" 이런 식으로 만들어주래

 

여기서 products/p1이라고하면
:productId가 p1이 되는거임.

 

 

App.js

import { RouterProvider, createBrowserRouter } from "react-router-dom";
import RootElement from "./components/UI/RootElement";
import Welcome from "./components/UI/Welcome";
import Products from "./components/UI/Products";
import ProductDetail from "./components/UI/ProductDetail";

const router = createBrowserRouter([{
  path: '/',
  element: <RootElement/>,
  children:[
    {
      path: '/welcome', element: <Welcome/>
    },
    {
      path: '/products', element: <Products/>
    },
    {
      path: '/products/:productId', element: <ProductDetail/>
    },
  ]

}])

function App() {
  return (
    <RouterProvider router={router}>
    </RouterProvider>
  );
}

export default App;

 

 

Product.js

 

import React from 'react';
import { Link } from 'react-router-dom';


const Products = () => {
    return (
        <div>
            <section>
                <nav>
                    <ul>
                        <li>
                            <Link to="/products/p1">1번 상품</Link>
                        </li>
                        <li>
                             <Link to="/products/p2">2번 상품</Link>
                        </li>
                    </ul>
                </nav>
            </section>
        </div>
    );
};

export default Products;

 

 

ProductDetail.js

 

import React from 'react';
import { useParams } from 'react-router-dom';

const ProductDetail = () => {
    const params = useParams();
    console.log(params);
    return (
       <section>
        <p>{params.ProductId}</p>
       </section>
    );
};

export default ProductDetail;

 

동적파라미터

 

여기서 :productId는 동적인 URL 파라미터를 나타냅니다. 콜론(:) 다음에 나오는 부분은 파라미터의 이름을 정의하는 것이며, 이 경우 "productId"로 정의되었습니다. 이러한 동적 파라미터는 URL의 일부로 들어오는 값에 따라 동적으로 페이지를 렌더링할 때 사용됩니다.

예를 들어, /products/123과 같은 URL에서 "123"은 "productId" 파라미터의 값으로 사용됩니다. 이러한 동적 파라미터를 통해 ProductDetail 컴포넌트는 URL에서 "productId" 값을 추출하여 해당 제품의 상세 정보를 표시할 수 있습니다.

 

 

 

import React from 'react';
import { useParams } from 'react-router-dom';

const ProductDetail = () => {
    const params = useParams();
    console.log(params);
    return (
       <section>
        <p>{params.productId}</p>
       </section>
    );
};

export default ProductDetail;

에러페이지 만들어줄 떄 제일 head 쪽에 errorElement: 쓰고
<ErrorPage />라는 컴포넌트를 하나 만들어주겠데

 

App.js

 

import { RouterProvider, createBrowserRouter } from "react-router-dom";
import RootElement from "./components/UI/RootElement";
import Welcome from "./components/UI/Welcome";
import Products from "./components/UI/Products";
import ProductDetail from "./components/UI/ProductDetail";
import ErrorPage from "./components/ErrorPage";

const router = createBrowserRouter([{
  path: '/',
  element: <RootElement/>,
  errorElement: <ErrorPage />,
  children:[
    {
      path: '/welcome', element: <Welcome/>
    },
    {
      path: '/products', element: <Products/>
    },
    {
      path: '/products/:productId', element: <ProductDetail/>
    },
  ]

}])

function App() {
  return (
    <RouterProvider router={router}>
    </RouterProvider>
  );
}

export default App;

 

import React from 'react';

const ErrorPage = () => {
    return (
        <div>
            This is an errorPage
        </div>
    );
};

export default ErrorPage;
반응형

'PROGRAMMING > React' 카테고리의 다른 글

타입스크립트  (0) 2023.10.05
useEffect 함수  (0) 2023.10.04
useEffect 훅  (1) 2023.10.01
[비공개] 리액트 폴더 구조  (0) 2023.09.18
리액트 개발환경 구축 0부터 (처음부터)  (0) 2023.09.05