-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a33540b
commit e823e4c
Showing
6 changed files
with
382 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
# Reactjs Custom Fetch Hooks | ||
|
||
### Usage and Installation | ||
change directory to your `src/ ` and execute the following comand: | ||
|
||
```bash | ||
git clone https://github.com/Newton-Nganga/awesome-react-fetch-hooks.git hooks/ | ||
``` | ||
|
||
Lastly execute this command to clean up the directory: | ||
|
||
```bash | ||
cd hooks/ ; sudo rm -r .git/ | ||
``` | ||
|
||
And vwalaah! you can now import the hooks where you need them. | ||
|
||
### Preliquisites | ||
- Be using Reactjs or Vite | ||
|
||
|
||
#### Example of useDataFetch hook looks like | ||
|
||
```js | ||
|
||
/* eslint-disable react-hooks/exhaustive-deps */ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
|
||
import { useEffect, useState } from "react"; | ||
|
||
export default function useDataFetch(url, options) { | ||
const opt = options ? options : {}; | ||
const [responseData, setResponseData] = useState(null); | ||
const [error, setError] = useState(null); | ||
const [isLoading, setLoading] = useState(false); | ||
|
||
const fetchData = async () => { | ||
setLoading(true); | ||
|
||
try { | ||
const response = await fetch(url, { | ||
...opt, | ||
method: "GET", | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Accept": "application/json", | ||
...opt?.headers, | ||
}, | ||
}); | ||
const data = await response.json(); | ||
setResponseData(data); | ||
} catch (error) { | ||
setError(error); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
fetchData(); | ||
}, [url, options]); | ||
|
||
const refetch = () => { | ||
fetchData(); | ||
}; | ||
|
||
return { responseData, error, isLoading, refetch }; | ||
} | ||
``` | ||
### Get Started | ||
After initializing the hook into your app | ||
#### Importing the Hook | ||
```js | ||
import useDataFetch from "hooks/useDataFetch"; | ||
``` | ||
#### Setting up the URL and Options | ||
Define the URL for the API endpoint and any necessary options for the fetch request. | ||
```js | ||
|
||
const url = "http://localhost:8080/api/data"; | ||
|
||
const options = { | ||
headers: { | ||
"Content-Type": "application/json", | ||
"Authorization": "Bearer wsvhvccmnm" | ||
} | ||
}; | ||
|
||
``` | ||
### Order of Handling the Returned items | ||
- Handle Loading State First | ||
- Handle Errors | ||
- Display or Use Data | ||
### Handling Loading State | ||
Check if the loading state is active and display a loading indicator. | ||
```js | ||
|
||
if (isLoading) { | ||
//do sth incase resource is still loading.. | ||
return <div>Loading...</div>; | ||
} | ||
``` | ||
### Handling Errors | ||
Check if an error occurred and handle it accordingly. | ||
```js | ||
//do sth incase an error is caught ... | ||
if (error) { | ||
return <div>Error: {error.message}</div>; | ||
} | ||
``` | ||
#### Displaying Data | ||
If loading is complete and no errors occurred, display the fetched data. | ||
```js | ||
//do sth when the action is complete | ||
return ( | ||
<> | ||
{responseData && responseData.map((item) => ( | ||
<div key={item.id}>{item.name}</div> | ||
))} | ||
</> | ||
); | ||
``` | ||
### sample complete usage of the hooks | ||
```js | ||
import React from "react"; | ||
import useUpdateData from "hooks/useUpdateData"; | ||
|
||
const DataUpdatingComponent = () => { | ||
|
||
const userId="1003" | ||
const url = `http://localhost:8080/api/data/${userId}`; | ||
|
||
//options could be empty but url can't be null/empty | ||
const options = { | ||
headers: { | ||
// "Content-Type": "application/json", --by default this is the set | ||
"Authorization": "Bearer wsvhvccmnm" | ||
} | ||
//...more otions | ||
}; | ||
|
||
const { responseData, error, isLoading, updateData } = useUpdateData(url, options); | ||
//your handle update function | ||
const handleUpdate = () => { | ||
const updatedData = { | ||
// the data/ fields you want to update | ||
name:"John" | ||
email: "[email protected]" | ||
}; | ||
//call the upData method from the hook and pass in the updated data object | ||
updateData(updatedData); | ||
}; | ||
//handle loading state | ||
if (isLoading) { | ||
return <div>Loading...</div>; | ||
} | ||
//handle an error if its caught | ||
if (error) { | ||
return <div>Error: {error.message}</div>; | ||
} | ||
//do sth with the responseData returned | ||
if(responseData.status.ok){ | ||
toast.success("item updated successfully") | ||
} | ||
return ( | ||
<> | ||
//the rest of the app | ||
<button onClick={handleUpdate}>Update Data</button> | ||
// the rest of the app | ||
</> | ||
); | ||
}; | ||
|
||
export default DataUpdatingComponent; | ||
``` | ||
#### Created By | ||
created by [Newton]("https://github.com/Newton-Nganga/") for reusability. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* eslint-disable react-hooks/exhaustive-deps */ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
|
||
import { useState } from "react"; | ||
|
||
export default function useCreateData(url, options) { | ||
const [data, setData] = useState(null); | ||
const [error, setError] = useState(null); | ||
const [isLoading, setLoading] = useState(false); | ||
|
||
const createData = async (newData) => { | ||
setLoading(true); | ||
|
||
try { | ||
const response = await fetch(url, { | ||
...options, | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
...options?.headers, | ||
}, | ||
body: JSON.stringify(newData), | ||
}); | ||
|
||
const result = await response.json(); | ||
setData(result); | ||
} catch (error) { | ||
setError(error); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
return { data, error, isLoading, createData }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* eslint-disable react-hooks/exhaustive-deps */ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
|
||
import { useState } from "react"; | ||
|
||
export default function useDeleteData(url, options) { | ||
const opt = options ? options : {} | ||
const [responseData, setResponseData] = useState(null); | ||
const [error, setError] = useState(null); | ||
const [isLoading, setLoading] = useState(false); | ||
|
||
|
||
const deleteData = async () => { | ||
setLoading(true); | ||
|
||
try { | ||
const response = await fetch(url, { | ||
...opt, | ||
method: 'DELETE', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
...opt?.headers, | ||
}, | ||
}); | ||
|
||
const result = await response.json(); | ||
setResponseData(result); | ||
} catch (error) { | ||
setError(error); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
return { responseData, error, isLoading, deleteData }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* eslint-disable react-hooks/exhaustive-deps */ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
|
||
import { useEffect, useState } from "react"; | ||
|
||
export default function useDataFetch(url, options) { | ||
const opt = options ? options : {} | ||
const [responseData, setResponseData] = useState(null); | ||
const [error, setError] = useState(null); | ||
const [isLoading, setLoading] = useState(false); | ||
|
||
const fetchData = async () => { | ||
setLoading(true); | ||
|
||
try { | ||
const response = await fetch(url, { | ||
...opt, | ||
method:"GET", | ||
headers:{ | ||
'Content-Type': 'application/json', | ||
'Accept': 'application/json', | ||
...opt?.headers, | ||
} | ||
}); | ||
const data = await response.json(); | ||
setResponseData(data); | ||
} catch (error) { | ||
setError(error); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
fetchData(); | ||
}, [url, options]); | ||
|
||
const refetch = () => { | ||
fetchData(); | ||
}; | ||
|
||
return { responseData, error, isLoading, refetch }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* eslint-disable react-hooks/exhaustive-deps */ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
|
||
import { useState } from "react"; | ||
|
||
export default function useUpdateData(url,options) { | ||
const opt = options ? options : {} | ||
|
||
const [responseData, setresponseData] = useState(null); | ||
const [error, setError] = useState(null); | ||
const [isLoading, setLoading] = useState(false); | ||
|
||
const patchData = async (patchedData) => { | ||
setLoading(true); | ||
|
||
try { | ||
const response = await fetch(url, { | ||
...opt, | ||
method: 'PUT', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
...opt?.headers, | ||
}, | ||
body: JSON.stringify(patchedData), | ||
}); | ||
|
||
const result = await response.json(); | ||
setresponseData(result); | ||
} catch (error) { | ||
setError(error); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
return { responseData, error, isLoading, patchData }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* eslint-disable react-hooks/exhaustive-deps */ | ||
/* eslint-disable react-hooks/rules-of-hooks */ | ||
|
||
import { useState } from "react"; | ||
|
||
export default function useUpdateData(url,options) { | ||
const opt = options ? options : {} | ||
|
||
const [responseData, setresponseData] = useState(null); | ||
const [error, setError] = useState(null); | ||
const [isLoading, setLoading] = useState(false); | ||
|
||
const updateData = async (updatedData) => { | ||
setLoading(true); | ||
|
||
try { | ||
const response = await fetch(url, { | ||
...opt, | ||
method: 'PUT', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
...opt?.headers, | ||
}, | ||
body: JSON.stringify(updatedData), | ||
}); | ||
|
||
const result = await response.json(); | ||
setresponseData(result); | ||
} catch (error) { | ||
setError(error); | ||
} finally { | ||
setLoading(false); | ||
} | ||
}; | ||
|
||
return { responseData, error, isLoading, updateData }; | ||
} |