https://www.youtube.com/watch?v=7exOfIAKuWU&list=LL&index=2&t=35s
β // 1. using default fetch, useEffect, useState
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
const fetchData = async () => {
const res = await fetch(url);
const data = await res.json()
setData(data)
setIsLoading(false)
}
fetchData()
},[])
if(isLoading){
return <h2>Loading...</h2>
}
> development mode e useEffect 2 bar call hote pare,
avoid korar jonno <React.StrictMode> off korte hobe
β // 2. axios
> akbare resolve kore object akare data dey
import axios from "axios"
const [data, setData] = useState([]);
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState("")
useEffect(() => {
const fetchData = async () => {
const res = await axios.get(url);
setData(res.data)
setIsLoading(false)
}
fetchData()
},[])
// best approach for error handling
// after response
> data array
> status
// using promises => .then.then.then.catch
useEffect(() => {
axios
.get(url).then((res) => {
setData(res.data)
setIsLoading(false)
})
.catch(error => {
setError(error.message)
setIsLoading(false)
})
}, [])
if(isLoading){
return <h2>Loading...</h2>
}
if(error){
return <h2>{error}</h2>
}
// using async/await + error handling
useEffect(() => {
const getData = async () => {
try {
const res await axios.get(url)
setData(res.data)
} catch{ (error) => {
setError(error.message)
setIsLoading(false)
}
}
}
}, [])
// best way to use axios
> setup baseUrl same folder
or
> create axios.js
> const API = axios.create({
baseURL: "localhost"
})
export default API
// MORE: error handling
> promise can be handled two ways try/catch block with async/await OR .then().catch() method
// Then and Catch \\
axios.get('/my-api-route')
.then(res => {
// Work with the response...
}).catch(err => {
// Handle error
console.log(err);
});
// Try/Catch with async/await \\
try {
let res = await axios.get('/my-api-route');
// Work with the response...
} catch (err) {
if (err.response) {
// The client was given an error response (5xx, 4xx)
console.log(err.response.data);
console.log(err.response.status);
console.log(err.response.headers);
} else if (err.request) {
// The client never received a response, and the request was never left
} else {
// Anything else
}
}
// axios interceptor
Axios interceptors are function that Axios call for every request
we can intercept while request or while response
// 3. stale-while-revalidate
> stale old data
> fetch related kono help kore na,we can use fetch or axios with swr
> help state management after fetch data
// fetcher function
const fetcher = async (...arg) => {
const res = await axios.get(...arg);
return res.data;
}
const {data, error} = useSWR(url, fetcher, {
suspense: true
})
> see doc for what srw {...returns}
> fetcher function take custom hook er modde store kore bar bar use korte hobe
if(error){
return <p>error message</p>
}
// 4. react-query
> react query context api er moto data gulo { QueryClientProvider } provider er modde sent kore
> jei component gula data receive korbe segulo ke provider diye wrap korte hobe
> value hisabe client={queryClient} dite hobe, jeta akta class
import {QueryClientProvider, QueryClient} from "react-query"
const client = new QueryClient({
defaultOptions: {
queries: {
suspense: true
}
}
})
const {isLoading,
data: notes,
isError,
error,
refetch} = useQuery("cache key", () => )
> 1st param - cache key diye jodi data fetch korte chay tahole new kore request pathabe na cache key te store kora data take send korbe
<Suspense fallback={<Loading/>}>
<Data />
</Suspense>
π― React Query
β what is react query
> a library for fetching data in react application
β why?
1. since react is a ui library, there is no specific pattern for data fetching
2. typically we use useEffect hook for data fetching and useState hook to maintain component state like loading error or resulting data
3. if the data is needed throughout the app, we tend to use state management libraries
4. most of the state management libraries are good for working with client state
ex: "theme" for application/ whether a modal is open
5. state management libraries are not great for working with async or server state
β client state
Persisted in your app memory and accessing or updating it is synchronous
β server state
> Persisted remotely and requires asynchronous APIs for fetching or updating
> has shared ownership
> data can be updated by someone else without your knowledge
> UI data may not be in sync with the remote data
> challenging when you have to deal with caching, deduping multiple requests for the same data, updating stale data in the background, performance optimizations etc.
β course content
1. basic queries
2. poll data
3. React-Query dev tools
4. create reusable query hooks
5. query by id
6. parallel queries
7. dynamic queries
8. dependent queries
9. infinite & paginated queries
10. update data using mutation
11. invalidate queries
12. optimistic updates
13. axios interceptor
β project setup
1. new react project using create-react-app
2. setup an api endpoint that serves mock data for use in our application
3. setup react router and a few routes in the application
4. fetch data the traditional way using useEffect and useState
β create fake data
> yarn add json-server
> create db.json at root
> scripts : {
"server-json": "json-server --watch db.json --port 4000"
}
> yarn serve-json
β setup react-query
1. import QueryClientProvider and QueryClient
import {QueryClientProvider, QueryClient} from "react-query"
const client = new QueryClient({
defaultOptions: {
queries: {
suspense: true
}
}
})
2. wrap children with QueryClientProvider and pass client={QueryClient}
3. if need suspense, but it will causes boundary error
const client = new QueryClient({
defaultOptions: {
queries: {
suspense: true
}
}
})
also set {suspense: true} inside useQuery hook after fetcher function
4. need atlease 2 param
useQuery("unique-key", functionWhichReturnPromise)
functionWhichReturnPromise: this function will make request to server
β basic implementation
import { useQuery } from "react-query";
import useAuthUserContext from "../context/AuthUserContext";
const { authUser } = useAuthUserContext();
// usually getting context takes time
// if found then try to fetch
const { isLoading, data: notes, isError, error, refetch} = useQuery("notes", () => authUser.user.email && getByEmail(authUser.user.email));
// if undefined at 1st approach then refetch again
if (!notes) {
refetch();
}
// if isLoading(fetching data) show loading component
if (isLoading) {
return <Loading />;
}
// if error occued while fetching show error message
if (isError) {
toast.error(error.message, {
id: "signUp error",
});
}
// finally data found then pass to child component
{notes && <NoteList notes={notes} refetch={refetch} />}
// then our child component
if {notes.length === 0 ? (<p>No Data<p>) : (notes.map((note) => <Note note={note}></Note>))}
β react query dev tool
> go to wrapper and import
import {ReactQueryDevtools} from "react-query/devtools"
> use this component before ending wrapper
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools initialIsOpen={false} position="bottom-right"/>
</QueryClientProvider>
β query cache
***cacheTime determines for how long a certain response is supposed to stay in cache before it gets garbage collected.
> by default react query will always cache request responst for 5 minitues(300000 millisecond)
> react query saved caches data by "unique-key" variable
> if cache which saved by unique-key is exist then show data without loading
> if data changes isLoading: false, isFetching: true
> after fetch update data isFetching: false
> if we want to change default cache time
useQuery("unique-key", fetcherFunction, { cacheTime: 5000})
> after finised cacheTime query cache data is garbage collected
β stale time (old data)
*** staleTime determines for how long a certain response will still be considered fresh (or not stale), dismissing the need for a new request.
> for doesnt necessarily changed ofted
> like our productslist or userlist are not changed ofted
> then we can use our cached query results and reduce unnecessary request
> if data changes we can set cache time for 30 sec
useQuery("unique-key", fetcherFunction, { staleTime: 30000})
> default staleTime:0
β cacheTime vs staleTime
https://stackoverflow.com/a/72833550/15497939 β
https://tkdodo.eu/blog/practical-react-query#the-defaults-explained β
https://medium.com/doctolib/react-query-cachetime-vs-staletime-ec74defc483e π€
StaleTime: The duration until a query transitions from fresh to stale. As long as the query is fresh, data will always be read from the cache only - no network request will happen! If the query is stale (which per default is: instantly), you will still get data from the cache, but a background refetch can happen under certain conditions.
CacheTime: The duration until inactive queries will be removed from the cache. This defaults to 5 minutes. Queries transition to the inactive state as soon as there are no observers registered, so when all components which use that query have unmounted.
β Refetch(pending...)
{
refetchOnMOunt: true
}
> If set to true, the query will refetch on mount if the data is stale.
β Mutations βββ
Mutations are used for Create, Update or Delete data from Database
// create
createNewNote(newNote);
export const useCreateNewNote = () =>{
return useMutation()
}
// use
const {mutate: createNote} = useCreateNewNote()
const handleCreateNote = () =>{
// newNote object
createNote(newNote)
}
β Axios Interceptor
import axios from "axios"
const client = axios.create({baseUrl: "localhost"})
export const request = ({...options}) => {
client.default.headers.commoon.Authorization = `Bearer token`
const onSuccess = res => res
const onError = error =>{
// optionally catch errors and add additional logging here
// redirect login page
return error
}
return client(options).then(onSuccess).catch(onError)
}
import {request} from "../utils/axios-utils"
export const fetchData = () {
// return axios.get("localhost/users")
return request(url: "/users")
}
export const addUser = (user) {
// return axios.post("localhost/post", user, {{headers:}})
return request({url: "/post", method: "post", data: user})
}
Created
November 15, 2022 16:07
-
-
Save nurmdrafi/f79e379d8d7cb601c1519c0c4a2c4d4e to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment