내일배움캠프

230719 리액트쿼리 파이어베이스에서 사용하기 (react-query firebase)

Neda 2023. 7. 19. 20:53

230719 리액트쿼리 파이어베이스에서 사용하기

리액트 쿼리는 서버에서 데이터를 가져오거나 캐싱, 업데이트 등을 수행하는 라이브러리이다.
리액트쿼리는 rest api 뿐만 아니라 파이어베이스 웹 sdk에도 사용할 수 있다.
리액트 쿼리를 사용해 파이어베이스의 데이터를 쿼리하고 뮤테이션하는 방법을 알아본다

파이어베이스 함수

  • 문서 가져오기 -> getDocs
  • 문서 생성 -> addDoc
  • 문서 삭제 -> deleteDoc
import { getDocs } from 'firebase/firestore'

export const getTodos = async () => {
  const querySnapshot = await getDocs(collection(db, 'todos'));
  return querySnapshot.docs.map((doc) => ({id:doc.id,...doc.data()}));
};

export const addTodo = async ({ content }) => {
  await addDoc(collection(db, "todos"), {
    content
  });
}

export const deleteTodo = async({ id }) => {
  await deleteDoc(doc(db, "todos", id));
}

 

리액트 쿼리를 사용해 파이어 베이스 사용

  • 데이터 가져오기 -> useQuery
  • 데이터  조작(생성, 삭제, 변경 등) -> useMutation
function Todos() {
  const queryClient = useQueryClient()

  const { isLoading, isError, data, error } = useQuery({ queryKey: ['todos'], queryFn: getTodos })

  const mutationAddTodo = useMutation({
    mutationFn: addTodo,
    onSuccess: () => {
      // Invalidate and refetch
      queryClient.invalidateQueries({ queryKey: ['todos'] })
    },
    onError: (error) => {
    // An error happened!
    console.log(`Add Todo Error ${error}`)
    }
  })
  
  const mutationDeleteTodo = useMutation({
    mutationFn: deleteTodo,
    onSuccess: () => {
      // Invalidate and refetch
      queryClient.invalidateQueries({ queryKey: ['todos'] })
    },
    onError: (error) => {
    // An error happened!
    console.log(`Delete Todo Error ${error}`)
    }
  })
  
  if (isLoading) return <span>Loading...</span>
  if (isError) return <span>Error: {error.message}</span>
  
  return (
    <div>
      <ul>
        {data?.map((todo) => (
          <li key={todo.id}>
            {todo.content}
            <button
              onClick={() => {
                mutationDeleteTodo.mutate({
                  id:todo.id
                })
              }}
            > 
              Delete Todo
            </button>
          </li>
        ))}
      </ul>
      <button
        onClick={() => {
          mutationAddTodo.mutate({
            content: 'newTodo'
          })
        }}
      >
        Add Todo
      </button>
    </div>
  )
}