-
Notifications
You must be signed in to change notification settings - Fork 3
08. Libraries and their common uses
Official Docs:
- Zustand - Application state management
- React Query - Data fetching/syncing
- React Hook Form - Forms
- AG Grid - React grids & tables
- Material UI - React theming & component library
- React - Frontend library
- FastAPI - Backend framework
- SQLAlchemy - Backend ORM
- Alembic - Database migration tool
- Pydantic - Backend Data validation library
- Vite - Frontend bundler
Guideline on common usage of libraries
Stores go in the ./frontend/src/stores
directory. You can create more than one store
// /src/stores/useUserStore.js
import { create } from 'zustand'
export const useUserStore = create((set) => ({
user: null,
setUser: (user) => set({ user })
}))
// to use in other components
import { useUserStore } from '@/stores/useUserStore'
export const ExamplePage = () => {
const user = useUserStore(state => state.user);
// or if importing multiple it might be easier to do this
const {user, setUser} = useUserStore({user, setUser} => ({user, setUser}))
return (
// jsx
)
}
By default React Query will cache fetched data unless otherwise set or invalidated
useQuery
is used to fetch data from an endpoint.
It is usually best to put this into a custom hook so that it can be easily used in other places.
// ./frontend/src/hooks/useUser.js
import { useQuery } from '@tanstack/react-query'
import { useApiService } from '@/services/useApiService'
export const useGetUser = (options, keys) => {
const client = useApiService()
return useQuery({
queryKey: ['user', ...keys],
queryFn: async () => (await client.get(`/users/${id}`)).data,
...options
})
}
Available options listed here
Keys are used to identify cache. Whenever a key is updated, it will automatically invalidate the data. You can also manually trigger an invalidation ( more on that below )
To use the custom hook:
import { useGetUser } from '@/hooks/useUser'
export const ExampleComponent = () => {
const { data, isLoading } = useGetUser()
return (
//jsx
)
}
You will have direct access to all properties listed here
Mutations can also be handled inside a custom hook using useMutation
// ./frontend/src/hooks/useUser.js
import { useMutation } from '@tanstack/react-query'
import { useApiService } from '@/services/useApiService'
export const usePostUser = (options, data) => {
const client = useApiService()
return useMutation({
mutationFn: async (data) => (await client.post(`/users/${id}`), data),
...options
})
}
Available options listed here
To use the custom hook:
import { usePostUser } from '@/hooks/useUser'
export const ExampleComponent = () => {
const { mutate } = usePostUser({
onSuccess: () => { console.log('success') },
onError: () => { console.log('error') }
})
const handleClick = () => {
mutate(data)
}
return (
//jsx
)
}
When you need to retrieve fresh data, we can invalidate the cache
import { useQueryClient } from 'react-query'
export const ExampleComponent = () => {
const queryClient = useQueryClient()
queryClient.invalidateQueryKey({queryKey: ['user']}) // the key associated with the query that is to be invalidated
return (
//jsx
)
}