본문 바로가기

블록체인_9기/🩵 React

48강_230706_React(Hook 함수(useNavigate, useLocation, useParams, useSearchParams), 상점 사이트 제작 )

728x90

 

 

 

 


Hook 함수

💛 useNavigate

  • 페이지를 이동할 때 사용된다.
  • 특정이벤트가 실행됐을 때 동작하도록 하거나 추가적인 로직이 필요한 경우 사용한다.

💛 useLocation

  • 현재 브라우저의 URL 위치 값을 가져오는데 사용한다.
  • 예) http://localhost:5500/main/2/33/test => /main/2/33/test 의 값을 가져온다.
    • 그 외에도 search, hash 등의 값을 가져온다.

💛 useParams

  • URL에 params 값을 접근하는데 사용한다.
  • params 값을 객체 형태로 가져올 수 있다.
  • 예) {id: '2', num: '33', name: 'test '}

💛 useSearchParams

  • URL의 query 값을 가져올 때 사용한다.
  • 문자열을 해석해서 쿼리 매개변수의 값을 가져온다.
  • 예) URL : http://localhost:5500//main/2/33/test?id=7
    • console.log(query.get("id"));
      • 결과 값: 7

 

 

 


상점 사이트 제작

#. 폴더의 경로는 다음과 같다.

1. App.js_부모 컴포넌트로서 로그인의 정보를 가지고 있으며, Route와 Navigate를 이용하여 컴파운드를 render시킨다.

  • Route 페이지 이동
    • '/login' 로그인 페이지로 이동하면 Login컴포넌트에 setLogin을 보내 Login컴포넌트에서 수정된 로그인 상태를 App컴포넌트에 적용하도록 한다. 
    • '/mypage' 로 이동하면 Redirect 함수를 실행한다. Redirect함수에서 로그인 유무를 확인하여 로그인이 되어있지 않은 상태면 로그인을 진행할 수 있도록 Navigate로 '/login'페이지로 이동한다.
    • '/detail/:id/:num/:name'는 각 상품별로 고유의 정보를 넣을 수 있도록 만들어준 값이다. 자세한 내용은 Detail 컴포넌트 설명에서 찾아보면 된다.
import "./App.css";
import { Routes, Route, Navigate } from "react-router-dom";
import { Detail, Login, Main, Mypage, Shop } from "./pages";
import { useState } from "react";
function App() {
  // 로그인 정보는 계속 자식에게 넘겨주어야 하므로 가장 부모컴포넌트에 넣어야 한다.
  const [login, setLogin] = useState(false);
  const Redirect = () => {
    // Navigate: 브라우저의 경로를 바꿔준다.
    // 페이지 리다이렉트 가능하다.
    // 로그인 될 수 있을 때만 볼 수 있어, mypage는 보호받는 페이지가 될 것이다.
    // 로그인이 안되어있는 상태면 메인페이지로 이동시킨다.
    return login == true ? (
      <Mypage login={login} />
    ) : (
      <Navigate to={"/login"} />
    );
  };
  return (
    <div className="App">
      {/* 페이지에 대한 라우터 설정 */}
      <Routes>
        <Route path="/" element={<Main login={login} />} />
        <Route
          path="/login"
          element={<Login login={login} setLogin={setLogin} />}
        />
        <Route path="/shop" element={<Shop login={login} />} />
        {/* 매개변수 데이터베이스의 id: 해당 상품의 id / num: 해당 상품의 번호 / name: 해당 상품의 이름  */}
        <Route
          path="/detail/:id/:num/:name"
          element={<Detail login={login} />}
        />
        {/* 로그인 상태일 경우에만 접속이 가능하도록 제작 */}
        <Route path="/mypage" element={<Redirect />} />
      </Routes>
    </div>
  );
}

export default App;

 

1. Body.jsx_Link, Navigate 함수를 사용하여 페이지 이동을 한다.

  • main.jsx에서 받아온 path, name, login 값을 이용하여 render한다.
    • path 값을 받아 각 페이지별로 유효한 링크를 받아 이동한다.
    • name 값을 받아 각 페이지가 어떤 페이지인지 알려준다.
    • login 값을 받아 현재 로그인 상태를 알려준다.
  • Shop.jsx에서 받아온 path, name, login, item 값을 이용하여 render한다.
    • 각 아이템별로 필요한 값을 item 값으로 넘겨준다.
import React from "react";

import { Link, useNavigate } from "react-router-dom";

const Body = ({ path, name, login, item }) => {
  const nav = useNavigate();
  return (
    <div className="body">
      <Link to={path}>{name} 페이지 이동</Link>
      <button
        onClick={() => {
          nav(path);
        }}
      >
        {name}페이지이동
      </button>
      {item && item.id ? <div>{item.id}</div> : null}
      {item && item.num ? <div>{item.num}번</div> : null}
      {item && item.name ? <div>이름 : {item.name}</div> : null}
      {login ? <div>로그인 옼옼</div> : <div>로그인 노노</div>}
    </div>
  );
};

export default Body;

 

2. Login.jsx_Link, Navigate 함수를 사용하여 페이지 이동을 한다.

  • '로그인/로그아웃' 버튼을 클릭하여 로그인 상태를 반전 시켜준다.
import React from "react";
import { Header, Body } from "../components";

const Login = ({ login, setLogin }) => {
  return (
    <div>
      <Header name={"로그인 페이지"}></Header>
      {/* JS가 코드를 읽는 과정에서 함수에 ()가 있으면 실행식이다.
        jsx 문법에서는 중괄호{}는 JS를 사용하겠다고 알려주는 건데
        힘수에 괄호를 쓰면 함수 실행식으로 받아들여서 함수를 실행시킨다.

        (o゚v゚)ノ 그러면 매개변수를 사용해야 할 경우에는???
        함수도 값이라고 했는데 익명함수를 만들어서 그 값을 전달하면 된다.  */}
      <button
        onClick={() => {
          setLogin(!login);
        }}
      >
        로그인/로그아웃
      </button>
      <Body path={"/"} name={"메인"} login={login}></Body>
    </div>
  );
};

export default Login;

 

3. Shop.jsx_각 상품별 정보를 담아 Body 컴포넌트로 보내 값을 render한다.

import React from "react";
import { Body, Header } from "../components";

const Shop = ({ login }) => {
  return (
    <div>
      <Header name={"상점 페이지"}></Header>

      <Body path={"/"} name={"메인"} login={login} />
      <Body path={"/detail"} name={"상세"} login={login} />

      <Body
        name={"1번 상품으로 이동"}
        path={"/detail/0/10/셔츠"}
        item={{ id: 0, num: 10, name: "셔츠" }}
      />
      <Body
        name={"2번 상품으로 이동"}
        path={"/detail/1/20/바지"}
        item={{ id: 1, num: 20, name: "바지" }}
      />
      <Body
        name={"3번 상품으로 이동"}
        path={"/detail/2/30/모자"}
        item={{ id: 2, num: 30, name: "모자" }}
      />
      <Body
        name={"4번 상품으로 이동"}
        path={"/detail/3/40/장갑"}
        item={{ id: 3, num: 40, name: "장갑" }}
      />
    </div>
  );
};

export default Shop;

 

4. Detail.jsx_각 상품별 고유한 url 정보를 받아 상품 정보를 노출한다.

import React from "react";
import { Header } from "../components";

import { useLocation, useParams, useSearchParams } from "react-router-dom";

const Detail = () => {
  let temp = [
    { num: 10, name: "셔츠" },
    { num: 20, name: "바지" },
    { num: 30, name: "모자" },
    { num: 40, name: "장갑" },
  ];
  const location = useLocation();

  const params = useParams();

  const [query, setQuery] = useSearchParams();

  return (
    <div>
      <Header name={"상세 페이지"}></Header>
      <div>{temp && temp[params.id].num} 번</div>
      <div>이름{temp && temp[params.id].name}</div>
    </div>
  );
};

export default Detail;

 

 

728x90