[NextJS] URL hash(#)

kimhayeon·2025년 1월 15일
0

Next.js

목록 보기
1/1

hash 값 가져오기

NextJS는 useParams, useSearchParams와 같이 url에 접근하기 위한 함수를 제공한다.
하지만 Hash(#)에 접근할 수 있는 함수는 찾지 못했다.
따라서 window 객체를 통해 접근했다.

console.log(window.location.hash)

hash 변경하기

구글링을 하면 useHash라는 Custom Hook을 발견할 수 있다.

Event(hashchange) 감지

hashchange 이벤트를 감지해서 hash를 업데이트하는 방식이다.
예상 외로 잘 동작하지 않는다.

'use client';

import { useEffect, useState } from 'react';

const getHash = () =>
  typeof window !== 'undefined'
    ? decodeURIComponent(window.location.hash.replace('#', ''))
    : undefined;

export default function useHash() {
  const [hash, setHash] = useState(getHash());

  useEffect(() => {
    const handleHashChange = () => {
      setHash(getHash());
    };
    
    window.addEventListener('hashchange', handleHashChange);
    
    return () => {
      window.removeEventListener('hashchange', handleHashChange);
    };
  }, []);

  return hash;
};

useRouter를 사용하여 Hash를 변경해도 이벤트가 발생하지 않기 때문이다.

window.location.hash에 직접 할당해도 동작하지 않는데, 아래와 같이 코드를 변경하면 정상적으로 동작한다.

window.addEventListener('hashchange', handleHashChange, false);

기존 실패의 원인은 이벤트가 window까지 전파되지 않은 것으로 생각된다.

그러나 false를 추가하더라도 useRouter를 사용하여 hash를 변경하면 여전히 이벤트가 발생하지 않는다.

useParams return 값 감지

다른 방법도 소개되어 있다. useParamsreturn 값을 useEffect 의존성 배열에 추가하는 것이다.

'use client';

import { useEffect, useState } from 'react';

const getHash = () => window ? decodeURIComponent(window.location.hash.replace('#', '')) : undefined;

export default function useHash() {
  const [hash, setHash] = useState(getHash());
  const params = useParams();

  useEffect(() => {
    setHash(getHash());
  }, [params]);

  return hash;
};

hash가 바뀌어도 params가 바뀌진 않기에 작동하지 않는다.

changeHash 함수

hash 변경 시, hash 상태를 업데이트하는 함수도 고려해 보았다.

export default function useHash() {
  const [hash, setHash] = useState(getHash());
  const params = useParams();
  const changeHash = (hash: string) => {
    router.push(hash);
    setHash(hash);
  };

  return { hash, changeHash };
};

이는 체택하지 않았다.
상위 컴포넌트에서 hash를 사용하고, 하위 컴포넌트에서 hash를 변경하는 경우, changeHash를 하위 컴포넌트로 전달해야 하기 때문이다.

0개의 댓글