Skip to content

Commit f9627d4

Browse files
authored
Dependency for onMount onUpdate (#145)
* first steps * useFetch changes * missed * got working + tests working * added onNewData * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * cleanup
1 parent 80b08f7 commit f9627d4

File tree

8 files changed

+277
-168
lines changed

8 files changed

+277
-168
lines changed

README.md

+96-55
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ Usage
8989

9090
<details open><summary><b>Basic Usage (managed state) <code>useFetch</code></b></summary>
9191

92+
If the last argument of `useFetch` is not a dependency array `[]`, then it will not fire until you call one of the http methods like `get`, `post`, etc.
93+
9294
```js
9395
import useFetch from 'use-http'
9496

@@ -131,18 +133,20 @@ function Todos() {
131133
```
132134
</details>
133135
134-
<details open><summary><b>Basic Usage (no managed state) <code>useFetch</code></b></summary>
135-
136+
<details><summary><b>Basic Usage (no managed state) <code>useFetch</code></b></summary>
137+
138+
This fetch is run `onMount/componentDidMount`. The last argument `[]` means it will run `onMount`. If you pass it a variable like `[someVariable]`, it will run `onMount` and again whenever `someVariable` changes values (aka `onUpdate`). **If no method is specified, GET is the default**
139+
136140
```js
137141
import useFetch from 'use-http'
138142

139143
function Todos() {
140-
const options = { // accepts all `fetch` options
141-
onMount: true, // will fire on componentDidMount (GET by default)
142-
data: [] // setting default for `data` as array instead of undefined
144+
// accepts all `fetch` options
145+
const options = {
146+
data: [], // setting default for `data` as array instead of undefined
143147
}
144-
145-
const { loading, error, data } = useFetch('https://example.com/todos', options)
148+
149+
const { loading, error, data } = useFetch('https://example.com/todos', options, []) // onMount (GET by default)
146150

147151
return (
148152
<>
@@ -157,17 +161,16 @@ function Todos() {
157161
```
158162
</details>
159163
160-
<details open><summary><b>Basic Usage with <code>Provider</code></b></summary>
164+
<details open><summary><b>Basic Usage (no managed state) with <code>Provider</code></b></summary>
161165
162166
```js
163167
import useFetch, { Provider } from 'use-http'
164168

165169
function Todos() {
166170
const { loading, error, data } = useFetch({
167-
onMount: true,
168171
path: '/todos',
169172
data: []
170-
})
173+
}, []) // onMount
171174

172175
return (
173176
<>
@@ -191,6 +194,42 @@ const App = () => (
191194
192195
</details>
193196
197+
<details open><summary><b>Pagination + <code>Provider</code></b></summary>
198+
199+
The `onNewData` will take the current data, and the newly fetched data, and allow you to merge the two however you choose. In the example below, we are appending the new todos to the end of the current todos.
200+
201+
```jsx
202+
import useFetch, { Provider } from 'use-http'
203+
204+
const Todos = () => {
205+
const [page, setPage] = useState(1)
206+
207+
const { data, loading } = useFetch({
208+
path: `/todos?page=${page}&amountPerPage=15`,
209+
onNewData: (currTodos, newTodos) => [...currTodos, ...newTodos], // appends newly fetched todos
210+
data: []
211+
}, [page]) // runs onMount AND whenever the `page` updates (onUpdate)
212+
213+
return (
214+
<ul>
215+
{data.map(todo => <li key={todo.id}>{todo.title}</li>}
216+
{loading && 'Loading...'}
217+
{!loading && (
218+
<button onClick={() => setPage(page + 1)}>Load More Todos</button>
219+
)}
220+
</ul>
221+
)
222+
}
223+
224+
const App = () => (
225+
<Provider url='https://example.com'>
226+
<Todos />
227+
</Provider>
228+
)
229+
```
230+
231+
</details>
232+
194233
<details open><summary><b>Destructured <code>useFetch</code></b></summary>
195234
196235
⚠️ The `response` object cannot be destructured! (at least not currently) ️️⚠️
@@ -548,11 +587,10 @@ const Todos = () => {
548587
const { loading, error, data: todos } = useFetch(globalOptions => {
549588
delete globalOptions.headers.Accept
550589
return {
551-
onMount: true,
552590
data: [],
553591
...globalOptions
554592
}
555-
})
593+
}, []) // onMount
556594

557595
// can also do this and overwrite the url like this
558596
// const { loading, error, data: todos } = useFetch('https://my-new-url.com', globalOptions => {
@@ -601,46 +639,73 @@ This is exactly what you would pass to the normal js `fetch`, with a little extr
601639
| Option | Description | Default |
602640
| --------------------- | --------------------------------------------------------------------------|------------- |
603641
| `url` | Allows you to set a base path so relative paths can be used for each request :) | empty string |
604-
| `onMount` | Once the component mounts, the http request will run immediately | `false` |
605-
| `onUpdate` | This is essentially the same as the dependency array for useEffect. Whenever one of the variables in this array is updated, the http request will re-run. | `[]` |
642+
| `onNewData` | Merges the current data with the incoming data. Great for pagination. | `(curr, new) => new` |
606643
| `onAbort` | Runs when the request is aborted. | empty function |
607644
| `onTimeout` | Called when the request times out. | empty function |
608645
| `retries` | When a request fails or times out, retry the request this many times. By default it will not retry. | `0` |
609646
| `timeout` | The request will be aborted/cancelled after this amount of time. This is also the interval at which `retries` will be made at. **in milliseconds** | `30000` </br> (30 seconds) |
610647
| `data` | Allows you to set a default value for `data` | `undefined` |
611-
| `loading` | Allows you to set default value for `loading` | `false` unless `onMount === true` |
648+
| `loading` | Allows you to set default value for `loading` | `false` unless the last argument of `useFetch` is `[]` |
612649
| `interceptors.request` | Allows you to do something before an http request is sent out. Useful for authentication if you need to refresh tokens a lot. | `undefined` |
613650
| `interceptors.response` | Allows you to do something after an http response is recieved. Useful for something like camelCasing the keys of the response. | `undefined` |
614651
615652
```jsx
616-
useFetch({
653+
const options = {
617654
// accepts all `fetch` options such as headers, method, etc.
618-
url: 'https://example.com', // used to be `baseUrl`
619-
onMount: true,
620-
onUpdate: [] // everytime a variable in this array is updated, it will re-run the request (GET by default)
621-
onTimeout: () => {}, // called when the request times out
622-
onAbort: () => {}, // called when aborting the request
623-
retries: 3, // amount of times it should retry before erroring out
624-
timeout: 10000, // amount of time before the request (or request(s) for retries) errors out.
625-
data: [], // default for `data` field
626-
loading: false, // default for `loading` field
627-
interceptors: { // typically, `interceptors` would be added as an option to the `<Provider />`
655+
656+
// used to be `baseUrl`. You can set your URL this way instead of as the 1st argument
657+
url: 'https://example.com',
658+
659+
// called when the request times out
660+
onTimeout: () => {},
661+
662+
// called when aborting the request
663+
onAbort: () => {},
664+
665+
// this will allow you to merge the data however you choose. Used for Pagination
666+
onNewData: (currData, newData) => {
667+
return [...currData, ...newData]
668+
},
669+
670+
// amount of times it should retry before erroring out
671+
retries: 3,
672+
673+
// amount of time before the request (or request(s) for each retry) errors out.
674+
timeout: 10000,
675+
676+
// set's the default for the `data` field
677+
data: [],
678+
679+
// set's the default for `loading` field
680+
loading: false,
681+
682+
// typically, `interceptors` would be added as an option to the `<Provider />`
683+
interceptors: {
628684
request: async (options) => { // `async` is not required
629685
return options // returning the `options` is important
630686
},
631687
response: (response) => {
632688
return response // returning the `response` is important
633689
}
634690
}
635-
})
691+
}
692+
693+
useFetch(options)
694+
// OR
695+
<Provider options={options}><ResOfYourApp /></Provider>
636696
```
637697
638-
Sponsors
639-
--------
698+
Who's using use-http?
699+
----------------------
640700
641701
Does your company use use-http? Consider sponsoring the project to fund new features, bug fixes, and more.
642702
643-
<a href="https://ava.inc" style="margin-right: 2rem;" target="_blank"><img width="280px" src="https://ava.inc/ava-logo-green.png" /></a>
703+
<a href="https://ava.inc" style="margin-right: 2rem;" target="_blank">
704+
<img width="200px" src="https://ava.inc/ava-logo-green.png" />
705+
</a>
706+
<a href="https://github.com/microsoft/DLWorkspace">
707+
<img height="200px" src="https://github.com/alex-cory/use-http/raw/master/public/microsoft-logo.png" />
708+
</a>
644709
645710
646711
Feature Requests/Ideas
@@ -745,37 +810,13 @@ Todos
745810
retryOnError: false,
746811

747812
refreshWhenHidden: false,
748-
749-
// this will allow you to merge the data the way you would like
750-
paginate: (currData, newData) => {
751-
return [...currData, ...newData]
752-
},
753813
})
754814
```
755815
- resources
756816
- [retryOn/retryDelay (fetch-retry)](https://www.npmjs.com/package/fetch-retry#example-retry-on-503-service-unavailable)
757817
- [retryDelay (react-query)](https://github.com/tannerlinsley/react-query)
758818
- [zeit's swr](https://github.com/zeit/swr)
759-
- [ ] potential syntax for pagination
760-
```js
761-
const App = () => {
762-
const [page, setPage] = useState(1)
763-
const { data, loading } = useFetch({
764-
onMount: true,
765-
onUpdate: [page],
766-
path: `/todos?page=${page}&pageSize=15`,
767-
paginate: (currData, newData) => [...currData, ...neweData],
768-
data: []
769-
})
770-
771-
return (
772-
<>
773-
{data.map(item => <div key={item.id}>{item.name}</div>}
774-
<button onClick={() => setPage(page + 1)}>Load More</button>
775-
</>
776-
)
777-
}
778-
```
819+
779820
- [ ] potential option ideas for `GraphQL`
780821
```jsx
781822
const request = useQuery({ onMount: true })`your graphql query`

0 commit comments

Comments
 (0)