Thanks to visit codestin.com
Credit goes to github.com

Skip to content

1nMarket/1n-market

 
 

Repository files navigation

1인마켓

주요기능

SEO 최적화

useTitle로 페이지 타이틀 최적화

각 페이지의 타이틀을 짓기 위해서 고민해서 다음과 같이 useTitle 훅을 만들어 해결했다.

import { useEffect } from 'react';

const useTitle = (title) => {
  useEffect(() => {
    const prevTitle = document.title;
    document.title = title;

    return () => (document.title = prevTitle);
  }, [title]);
};

export default useTitle;
스크린샷 2023-01-02 오후 2 07 45
ObserverIntersection Api 통해서 피드 무한스크롤 구현

트러블 슈팅

useDebounce 사용해서 검색 최적화하기

한 글자만 쳐도 검색되는 문제 발견. 필요없는 요청이 많아진다.

스크린샷 2023-01-02 오후 2 15 55

useDebounce 커스텀 훅

// hooks/useDebounce.js
import { useEffect, useState } from 'react';

const useDebounce = (value, delay) => {
  const [debouncedValue, setDebounceValue] = useState(value);

  useEffect(() => {
    const timer = setTimeout(() => setDebounceValue(value), delay || 500);

    return () => {
      clearTimeout(timer);
    };
  }, [value, delay]);

  return debouncedValue;
};

export default useDebounce;

useDbounce 훅 적용

const Search = () => {
  const [keyword, setKeyword] = useState('');
  const debouncedValue = useDebounce(keyword);
  const [searchList, setSearchList] = useState([]);

  useEffect(() => {
    if (!keyword.length) return;

    const searchUsers = async () => {
      const { data } = await axiosPrivate.get(
        `/user/searchuser/?keyword=${keyword}`,
      );
      setSearchList(data);
    };
    searchUsers();
  }, [debouncedValue]);

  return (
    <>
      <SearchHeader setKeyword={setKeyword} />
      <S.Content>
        <SearchList searchList={searchList} />
      </S.Content>
    </>
  );
};
스크린샷 2023-01-02 오후 2 29 22
  • 불필요한 리렌더링을 막을 수 있다.
memo 사용해서 피드 무한스크롤 시 이전 게시글 최적화 작업
토큰 검증을 통한 사용자 인증 확인

기존 RequireAuth 컴포넌트

const RequireAuth = () => {
  const token = JSON.parse(localStorage.getItem('token'));
  const location = useLocation();

  return (
    <>
      {token ? (
        <Outlet />
      ) : (
        <Navigate to='login' state={{ from: location }} replace />
      )}
    </>
  );
};

export default RequireAuth;
스크린샷 2023-01-02 오후 4 25 09

isValid 검증을 통해 알맞은 토큰인지 검증

const RequireAuth = () => {
  const token = JSON.parse(localStorage.getItem('token'));
  const location = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    const isValid = async () => {
      try {
        const { data: isValid } = await axiosPrivate.get('/user/checktoken');
        if (!isValid) {
          localStorage.removeItem('token');
          navigate('/login');
        }
      } catch (err) {
        localStorage.removeItem('token');
        navigate('/login');
      }
    };
    isValid();
  }, []);

  return (
    <>
      {token ? (
        <Outlet />
      ) : (
        <Navigate to='login' state={{ from: location }} replace />
      )}
    </>
  );
};

export default RequireAuth;
복잡한 경로 jsconfig.json으로 깔끔하게 정리하기

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 98.6%
  • HTML 1.4%