TIL_동적 라우팅 실습하기

이고운·2022년 8월 25일
0

1. 동적 라우팅 실습하기

(1) 필터 걸기

// Products.js
import { useEffect, useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";

function Products() {
  const [limit, setLimit] = useState(10);
  const [offset, setOffset] = useState(0);

  const location = useLocation();
  const navigate = useNavigate();
  const [products, setProducts] = useState([
    {
      id: 0,
      title: "상품제목",
      price: 1000,
    },
  ]);

  console.log("location", location);
  console.log("pathname", location.pathname);
  console.log("search", location.search);

  //navigate query바뀐 것 인식해서 useEffect 실행되면 됨. (location.search 이용해서) 그러므로 의존성 배열에 location.search 넣어줌.
  // 쿼리파라미터가 바뀌면 getFakeAPI도 다시 실행.
  useEffect(() => {
    const products = getFakeAPI(location.search);
    setProducts(products);
  }, [location.search]);

  //버튼 눌러서 가져오기 함수
  function onFetchClick() {
    navigate(`?limit=${limit}&offset=${offset}`);
  } //쿼리 파라미터를 다는게 네비게이트를 통해서 이루어지는게 중요!

  return (
    <>
      {/* 필터 옵션도 있을 것 - limit과 offiset 바꿀 수 있도록 */}
      <div>
        limit:{" "}
        <input value={limit} onChange={(e) => setLimit(e.target.value)} />
      </div>
      <div>
        offset:{" "}
        <input value={offset} onChange={(e) => setOffset(e.target.value)} />
      </div>
      <button onClick={onFetchClick}> 가져오기 </button>
      {products.map((product) => (
        <div key={product.id}>
          {product.id} {product.title} {product.price}
        </div>
      ))}
    </>
  );
}

export default Products;

// 백엔드 흉내내는 코드
function getFakeAPI(search) {
  const urlSerachParams = new URLSearchParams(search);
  const offset = urlSerachParams.get("offset");
  const limit = urlSerachParams.get("limit");
  // 백엔드에서는 req.query.offset, req.query.limit

  let index = offset;
  const fakeProducts = [];

  for (let i = 0; i < limit; i += 1) {
    const fakeProduct = {
      id: index,
      title: `상품제목${index}`,
      price: 1000 * Number(index),
    };
    index++;
    fakeProducts.push(fakeProduct);
  }

  return fakeProducts;
}

이전 기본 단계에서 바뀐 것 _UPDATE

  • input창 만들어서 limit, offset 검색하는 창 만들어줌.
  • useNavigate hook을 넣어서 데이터 가져오는 버튼 만들어줌.
  • useNavigate안에 query가 바뀐 것을 인식해서 location.search를 이용해 useEffect를 실행하게 함.
    쿼리파라미터가 바뀌면 getFakeAPI도 다시 실행되어 인풋창에 넣은
    limit, offset 값에 따라 setProducts도 바뀜.

<검색 전>

<검색 후> 가져오기 버튼 누르면 위에 검색한 limit, offset값에 따라
위에 쿼리파라미터가 바뀌고 상품조회됨.

(2) 상페 페이지 넘어가기

조회된 상품 목록 클릭하면 제품 상세페이지로 넘어가기

  • Link 이용하여 경로 설정해주기
  • 상세페이지(.js) route 설정해주기 (링크경로만 만들어주면 안됨. App.js에 route지정이 안되어있기 때문)
// App.js
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Users from "./Users";
import Products from "./Products";
import ProductDetail from "./ProductDetail";

function App() {
  return (
    <div>
      <BrowserRouter>
        <Routes>
          <Route path="users/:id" element={<Users />} />
          {/* //useParams hook통해서 id 값 가져옴 //특정 정보 가져올 때  */}
          <Route path="products" element={<Products />} />
          {/* //쿼리 파라미터 - 성질에 따라 바뀌게 될 때 / 쿼리파라미터는 패스파라미터랑 다르게 id 같이 등록할 필요 없음. search를 이용해 가져옴.*/}
          <Route path="product/:id" element={<ProductDetail />} /> // id값을 넣은 상세페이지 route
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;
//Product.js
  <button onClick={onFetchClick}> 가져오기 </button>
      {products.map((product) => (
        <Link key={product.id} to={`/product/${product.id}`}>
          {/* key도 위로 옮겨줌 Link가 최상단에 있으니까  */}
          {/* 그리고 이렇게 링크 경로를 만들어 주기만 하면 안되고 App.js에 route 지정이 안되어있어서 등록해줘야함. */}
          <div>
            {product.id} {product.title} {product.price}
          </div>
        </Link>
      ))}
기존에 있던 map의 key값도 최상단인 Link태그에 올려줌.
경로를 /product/아이디로 지정함.
```
```
//ProductDetail.js
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";

//배열 모양 까먹지 않기 기록해놓은 것.
// charges:[
//   {
//     id: 1,
//     name: "배송비",
//     price: 2500
//   }
// ],
// review: [
//   {
//     id: 0,
//     comment:" 너무 좋아요",
//     star: 4.5
//   }
// ]

function ProductDetail() {
  const [product, setProduct] = useState({
    id: 0,
    tite: "상품0",
    price: 0,
    charges: [],
    review: [],
  }); //여기서 기본값을 지정하지 않으면 밑에 product.id ~ 여기에
  undefined이 뜸. 그래서 초기값 설정해 준 것임.
  
  const params = useParams();
  const productId = params.id;
  //제품 상세 정보 가져오기
    useEffect(() => {
 //api호출
   const product = getFakeAPI(productId);
   setProduct(fakeProduct);
  }, [productId]);

  return (
    <>
      {product.id} {product.title} {product.price}
    </>
  );
}
export default ProductDetail;

<검색 전>

<검색 후>

<상세페이지 클릭하여 들어 간 후> ( 제품 정보 미등록으로 초기값으로 나옴)

profile
자 이제 시작이야~ 내 꿈을~ 내 꿈을 위한 여행~~🌈

0개의 댓글