yamoo9 / likelion-FEQA

질문/답변 — 프론트엔드 스쿨, 멋사
29 stars 9 forks source link

[LAB-17] 배포 후 a태그로 내부 id값으로 이동이 안되는 문제 #273

Closed nahee09 closed 1 year ago

nahee09 commented 1 year ago

질문 작성자

김나희

문제 상황

(InternalLinkMoveTest.jsx)

import {} from 'prop-types';

import {
  InternalLinkMoves,
  ProductReviewSection,
  ProductInquirySection,
} from '..';

import classes from './InternalLinkMoveTest.module.css';
import saladInfoImage from '@/assets/salad/detail_info.jpg';
import saladViewImage from '@/assets/salad/detail_view.jpg';

export function InternalLinkMoveTest() {
  const internalLinkList = [
    {
      id: 'item1',
      name: '상품설명',
      to: '#/productdetail#productDescription',
    },
    {
      id: 'item2',
      name: '상세정보',
      to: '#/productdetail#productDetailImage',
    },
    {
      id: 'item3',
      name: '후기',
      to: '#/productdetail#productReview',
      isNumberOption: true,
    },
    { id: 'item4', name: '문의', to: '#/productdetail#productInquiry' },
  ];

  return (
    <>
      <section className={classes.align}>
        <div className={classes.zIndex}>
          <InternalLinkMoves list={internalLinkList} title="상세 메뉴 리스트" />
        </div>
        <img
          alt="상품설명이미지"
          id="productDescription"
          src={saladViewImage}
        />
        <img
          alt="상품상세정보이미지"
          id="productDetailImage"
          src={saladInfoImage}
        />
        <section className={classes.productReview} id="productReview">
          <ProductReviewSection />
        </section>
        <section className={classes.productInquiry} id="productInquiry">
          <ProductInquirySection />
        </section>
      </section>
    </>
  );
}

(InternalLinkMove.jsx)

import { bool, string } from 'prop-types';

import classes from './InternalLinkMove.module.css';

export function InternalLinkMove({
  name,
  to,
  isNumberOption,
  id,
  className,
  anchorClass,
  ...restProps
}) {
  function putNumberOption(isNumberOption) {
    if (isNumberOption) {
      return <span>{'(1,000)'}</span>;
    }
  }

  const combineClassName = `${classes.internalLinkMove} ${className}`.trim();

  return (
    <li key={id} className={combineClassName} id={id} {...restProps}>
      <a className={anchorClass} href={to}>
        {name}
        {putNumberOption(isNumberOption)}
      </a>
    </li>
  );
}

프로젝트 저장소 URL

https://github.com/nahee09/NatureKarly/tree/hotfix/internal-link-move hotfix/internal-link-move 브랜치입니다.

환경 정보

yamoo9 commented 1 year ago

문제 원인

배포 후에 InternalLinkMoveTest.jsx 파일의 to 값을 to: '#id값'으로 하면 이상한 페이지로 이동을 했습니다. to: #/productdetail#id값'처럼 앞에 페이지 명을 명시해주면 클릭은 되는데 내부링크로 이동을 하지 않아 질문드립니다..!

배포된 웹 서비스의 라우트(route)를 보면 HashRouter 방식을 사용한 걸 알 수 있습니다.

HashRouter 방식은 /#/ 뒤에 라우트 경로를 붙여주는데, 이는 웹 브라우저가 서버에 새로운 페이지를 요청하지 않게 하고 React Router에 의해 페이지 렌더링을 처리합니다. 이름이 해시(hash)인 이유가 여기에 있죠.

웹 브라우저 주소 창에 다음과 같이 입력된 라우트(경로)를 분석해 웹 브라우저는 서버에 새로운 페이지를 요청합니다.

http://호스트이름:포트번호/패스이름

하지만 동일 라우트에서 해시(#)만 추가된 경우 웹 브라우저는 서버에 새 페이지를 요청하지 않습니다.

http://호스트이름:포트번호/패스이름#해시

이 점을 이용해 싱글 페이지 애플리케이션(SPA)을 구현하는 방법이 HashRouter 입니다. 즉, 이미 해시를 사용 중인데 뒤에 해시를 붙여봐야 소용이 없다는 말인 것이죠. 라우트의 해시는 이미 사용되었으니까요. 그래서 아무런 작동을 하지 않는 것입니다.

문제 해결

이 문제를 해결하는 로직을 작성하려면 다음 주제에 대해 이해해야 합니다.

위에 나열한 3가지를 다뤄 원하는 바를 구현해보세요. 😃 How to Scroll to Element in React 글이 도움이 될 거에요.

nahee09 commented 1 year ago

감사합니다 야무쌤!!!