오늘 한 일
- gloddy 개발
- 차단/신고 기능 추가
차단/신고 기능
아직 api가 나오지 않았는데, ios 배포를 위해 필요한 기능이라서 일단 클라이언트에서 처리해서 눈속임을 하려한다.
차단/신고 UI는 이미 만들어두었다. 이 기능을 사용할 수 있는 곳은 다음과 같다.
- 모임글
- 게시글
- 댓글
더보기 버튼(...)을 클릭하면 바텀시트가 올라오게 되는데, 여기서 차단/신고를 할 수 있다.
눈속임
차단/신고 버튼을 클릭하면 해당되는 글의 id와 글 타입(모임, 게시글, 댓글)을 localStorage에 저장한다. 그 다음 서버에서 받아온 데이터의 id와 스토리지의 id를 비교해서 같으면 안보이게 처리한다.
처음에 직접 localStorage를 조작하는 방식을 시도했는데 값이 바뀌어도 리렌더링이 되지 않았다.
알고보니 커스텀 훅을 여러군데에 사용하고 있어서 컴포넌트들이 동일한 state를 바라보고 있지 않아 발생한 문제였다. 그래서 zustand의 persist를 사용하여 localStorage에 저장하고, useBlockStore를 사용하여 상태를 관리하였다.
// useBlockStore.ts
import { create } from 'zustand'
import { createJSONStorage, persist } from 'zustand/middleware'
type BlockState = {
blockGroupIds: number[]
blockArticleIds: number[]
blockCommentIds: number[]
blockNoticeIds: number[]
setBlockId: (id: number, type: 'group' | 'article' | 'comment' | 'notice') => void
}
export const useBlockStore = create(
persist<BlockState>(
(set) => ({
blockArticleIds: [],
blockCommentIds: [],
blockGroupIds: [],
blockNoticeIds: [],
setBlockId: (id: number, type: 'group' | 'article' | 'comment' | 'notice') => {
set((state) => {
const capitalizedState = ('block' +
(type.charAt(0).toUpperCase() + type.slice(1)) +
'Ids') as keyof Omit<BlockState, 'setBlockId'>
if (state[capitalizedState].includes(id)) return state
return {
...state,
[capitalizedState]: [...state[capitalizedState], id],
}
})
},
}),
{
name: 'blockIds',
storage: createJSONStorage(() => localStorage),
}
)
)
이제 이 전역 상태를 통해 눈속임을 할 수 있게 되었다.
const { blockCommentIds } = useBlockStore();
const isBlocked = blockCommentIds.includes(comment.id);
if (isBlocked) return null;
return (
//...
)
persist?
사실 나는 redux를 제대로 써본 적이 없다. redux-persist를 들어보긴 했는데 어떤 역할을 하는 라이브러리인지 알지 못하고 있었다.
방금 같은 상황을 해결하기 위해 검색해보니 persist 얘기가 많이 나왔다.
redux-persist는 redux의 상태를 localStorage에 저장해주는 라이브러리였다. 또한 zustand에서도 persist를 제공하고 있었다.
zustand도 많이 활용해봐야겠다.
내일 할 일
- gloddy 개발