🎃쿼리스트링이란?
1. url 경로 (pathname) 다음에 나오는 ? 기호로 시작하는 문자열
2. key=value형태로 여러 개는 & 기호로 매개변수 명시 가능
⭐쿼리 스트링 사용 목적
1) 조건에 맞게 정렬된 형태로 정보 주고 받기 가능
2) 해당 Url로 공유 가능
⭐ URLSearchParams 객체 사용 이유
1. 쿼리 문자열 파싱 : 현재 페이지 URL의 쿼리 문자열 파싱에 사용 가능
2. 쿼리 문자열 생성 및 수정 : 카테고리 + 정렬 2가지를 사용하기 위해
새로운 문자열 생성 가능
3. 해당 객체는 'toString()'메소드를 통해 쉽게 문자열로 변환 가능
🚫구현하는데 시간이 오래 걸린 포인트
쿼리 스트링을 통해 라우팅이 된다는 점에
"Router.tsx'파일을 수정해야한다는 생각에 빠져있었음
=> Link 또는 navigate에 쿼리스트링이 포함된 주소를 전달하기만 하면 됨!
(URL에 추가 정보를 더하는 것 뿐, 라우터 컴포넌트에 설정할 내용이 없음)
🖥️구현 코드(1)
export type Category = 'knowHow' | 'recommendation' | 'sharing' | 'habit' | 'noCategory' | 'total';
export type SortList = 'popularity' | 'latest';
function ViewAllBody() {
const [category, setCategory] = useRecoilState<Category>(categoryListState);
const [sortBy, setSortBy] = useState<SortList>('latest');
const [searchParams, setSearchParams] = useSearchParams();
const navigate = useNavigate();
const updateSortOption = (newCategory: Category, newSortBy: SortList) => {
setCategory(newCategory);
setSortBy(newSortBy);
const newSearchParams = new URLSearchParams();
newSearchParams.set('category', newCategory);
newSearchParams.set('sort', newSortBy);
setSearchParams(newSearchParams);
navigate(`/viewAll/?${newSearchParams.toString()}`);
};
return (
<St.Button onClick={() => updateSortOption('total', sortBy)} selected={category === 'total'}>
전체보기
</St.Button>
<St.Button onClick={() => updateSortOption('knowHow', sortBy)} selected={category === 'knowHow'}>
노하우 공유
</St.Button>
)
1. URLSearchParams();
▶ new 키워드로 인스턴스 생성
▶ set(key, value) : 지정된 키 값 설정
(이미 있으면 업데이트 / 없으면 새로운 값 추가)
▶ navigate: 새 URL로 이동시키는 데 사용
🖥️구현 코드(2)
function ViewAllBody() {
const [category, setCategory] = useRecoilState<Category>(categoryListState);
const [sortBy, setSortBy] = useState<SortList>('latest');
const [searchParams, setSearchParams] = useSearchParams();
const validCategories: Category[] = ['knowHow', 'recommendation', 'sharing', 'habit', 'noCategory', 'total'];
const validSortOptions: SortList[] = ['popularity', 'latest'];
const navigate = useNavigate();
useEffect(() => {
// URL 쿼리 파라미터에서 category와 sort 값을 가져옵니다.
const urlCategory = searchParams.get('category');
const urlSortBy = searchParams.get('sort');
//카테고리 : 전체보기~기타
if (urlCategory && validCategories.includes(urlCategory as Category)) {
setCategory(urlCategory as Category);
} else {
setCategory('total');
}
//정렬 : 인기순 /최신순
if (urlSortBy && validSortOptions.includes(urlSortBy as SortList)) {
setSortBy(urlSortBy as SortList);
} else {
setSortBy('latest');
}
}, [searchParams]);
2. url로 이동하고 다른 브라우저에서 검색해도
동일한 화면 나오도록 하는 포인트 => useEffect 사용!
▶ searchParams.get : 각각의 값 가져오기
▶ useEffect
: 컴포넌트 마운트 + searchParams 변경될 때 실행
: validCategories & validSortOptions : 유효한 카테고리와 정렬 옵션을 정의
: 기본값으로는 'total'과 'latest'로 설정
🖥️구현 코드(2): 개선
function ViewAllBody() {
const [category, setCategory] = useRecoilState<Category>(categoryListState);
const [sortBy, setSortBy] = useState<SortList>('latest');
const [searchParams, setSearchParams] = useSearchParams();
const validCategories: Category[] = ['knowHow', 'recommendation', 'sharing', 'habit', 'noCategory', 'total'];
const validSortOptions: SortList[] = ['popularity', 'latest'];
const navigate = useNavigate();
const updateStateFromUrl = () => {
// URL 쿼리 파라미터에서 category와 sort 값을 가져옵니다.
const urlCategory = searchParams.get('category');
const urlSortBy = searchParams.get('sort');
//카테고리 : 전체보기~기타
if (urlCategory && validCategories.includes(urlCategory as Category)) {
setCategory(urlCategory as Category);
} else {
setCategory('total');
}
//정렬 : 인기순 /최신순
if (urlSortBy && validSortOptions.includes(urlSortBy as SortList)) {
setSortBy(urlSortBy as SortList);
} else {
setSortBy('latest');
}
};
//URL에서 상태 읽어오는 useEffect
useEffect(() => {
updateStateFromUrl();
}, [searchParams]);
//쿼리스트링 : 카테고리+정렬
const updateSortOption = (newCategory: Category, newSortBy: SortList) => {
setCategory(newCategory);
setSortBy(newSortBy);
const newSearchParams = new URLSearchParams();
newSearchParams.set('category', newCategory);
newSearchParams.set('sort', newSortBy);
setSearchParams(newSearchParams);
navigate(`/viewAll/?${newSearchParams.toString()}`);
};
//초기 마운트 실행시
useEffect(() => {
if (searchParams.get('category') === null || searchParams.get('sort') === null) {
updateSortOption(category, sortBy);
}
}, []);
▶ useEffect 2개 사용
1) URL에서 상태 읽어오는 useEffect
- 카테고리 & 정렬값이 변경될때마다 반영하기 위함
2) 초기 마운트 실행 사용되는 useEffect
- 컴포넌트 마운트되면 초기 설정값으로 url에 표시하기 위함
끝.
'TIL :: Today I Learned' 카테고리의 다른 글
리액트 prefetch 테스트 : prefetchInfiniteQuery 적용하기 (1) | 2024.01.25 |
---|---|
리액트 + 타입스크립트 : 카카오톡 공유 기능 추가 + 링크복사 구현 (0) | 2024.01.24 |
파이어베이스 오류 : The query requires an index (0) | 2024.01.22 |
타입스크립트 + useInfiniteQuery : 좋아요 기능 구현 (Optimistic Update) (0) | 2024.01.20 |
타입스크립트 + useInfiniteQuery : 더보기 기능 마지막 데이터 확인 (0) | 2024.01.18 |