2024.07.18 프로그래머스 - React 동적 UI 개발 5
React 기반 동적 UI 개발 - 5
로그인 flow
zustand를 통한 전역 상태 관리
설치
1
npm install zustand
authStore 작성
- src / store / authStore.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { create } from "zustand";
import { devtools, StateStorage } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";
interface StoreState {
isLoggedIn: boolean;
}
interface StoreAction {
storeLogin: (token: string) => void;
storeLogout: () => void;
}
export const useAuthStore = create<StoreState & StoreAction>()(
devtools(
immer((set) => ({
isLoggedIn: false,
storeLogin: (token: string) => set((state: StoreState) => {state.isLoggedIn = true}),
storeLogout: () => set((state: StoreState) => {state.isLoggedIn = false}),
})),
{ name: "authStore" }
)
);
- devtools 를 통해 Redux-develope 개발자 도구에서 store를 확인할 수 있다.
- immer를 통해 불변성 유지를 통한 state 로직 간소화를 진행할 수 있다.
쿼리 스트링 사용하기
React-router의 useSearchParams
훅을 사용하면, 현재 client 환경에서 현재 접속? 중인 url 쿼리 스트링을 수신할 수 있다.
이를 기반으로 기타 다른 이벤트 없이 쿼리스트링을 통해 조건부 렌더링을 수행 할 수 있다.
도서 카테고리 선택 코드 (BooksFilter.tsx)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
import React from "react"; import styled from "styled-components"; import { useCategory } from "../../../hooks/useCategory"; import Button from "../../../shared/components/Button"; import { useSearchParams } from "react-router-dom"; import { QUERYSTRING } from "../../../shared/constants/queryString"; function BooksFilter() { const { categories } = useCategory(); const [searchParams, setSearchParams] = useSearchParams(); const handleCategory = (id: number | null) => { const newSearchParams = new URLSearchParams(searchParams); console.log(newSearchParams); if (id === null) { newSearchParams.delete(QUERYSTRING.CATEGORY_ID); } else { newSearchParams.set(QUERYSTRING.CATEGORY_ID, id.toString()); newSearchParams.delete(QUERYSTRING.PAGE); } setSearchParams(newSearchParams); }; const handleNews = () => { const newSearchParams = new URLSearchParams(searchParams); if (newSearchParams.get(QUERYSTRING.NEWS)) { newSearchParams.delete(QUERYSTRING.NEWS); } else { newSearchParams.set(QUERYSTRING.NEWS, "true"); } setSearchParams(newSearchParams); }; return ( <BooksFilterStyle> <div className="category"> {categories.map((item) => ( <Button size="medium" scheme={item.isActive ? "primary" : "normal"} key={item.id} onClick={() => handleCategory(item.id)} > {item.name} </Button> ))} </div> <div className="new"> <Button size="medium" scheme={searchParams.get(QUERYSTRING.NEWS) ? "primary" : "normal"} onClick={handleNews} > 신간 </Button> </div> </BooksFilterStyle> ); } const BooksFilterStyle = styled.div` display: flex; gap: 24px; .category { display: flex; gap: 8px; } `; export default BooksFilter;
useSearchParams 는 배열을 반환한다.
- 첫번째 반환 값 : 현재 쿼리스트링 상태? 값
- 두번째 반환 값 : 쿼리스트링 setter
여기서 중요한점은 new URLSearchParams
를 통해 useSearchParams로 반환받은
현재 searchParams 값을 기반으로 쿼리스트링 객체를 생성 할 수 있다는 점이다.
URLSearchParams
인터페이스는 URL의 쿼리 문자열을 대상으로 작업할 수 있는 유틸리티 메서드를 정의합니다.
-MDN-
해당 method를 통해 useLocation으로 반환받은 location.search 와 같은 값 또한
객체 형태로의 간편한 사용이 가능해진다.
오늘 수강중 느낀점
확실히 구조를 이해하면서 하니까 어렵지만 프로젝트가 머리속에 들어온다.
이전에 강의에서 진행한 BE 코드를 같이 사용하는데,
나는 그 때 내 멋대로 작성해서, sql query 수정만 한 세월 한 것 같다.
풀스택 역량을 갖추는게 왜 어려운지 확연히 느낀 하루 였다.
그래도 한단계 또 성장한거 같아서 아주 이득이다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.