Skip to content

1st argument changes, remove "path" and "url" options, bug fixes #251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Apr 23, 2020
Merged
91 changes: 20 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<br />

<p align="center">
<a href="https://github.com/ava/use-http/pulls">
<a href="https://github.com/ava/use-http/blob/master/.github/contributing.md">
<img src="https://camo.githubusercontent.com/d4e0f63e9613ee474a7dfdc23c240b9795712c96/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5052732d77656c636f6d652d627269676874677265656e2e737667" />
</a>
<a href="https://circleci.com/gh/ava/use-http">
Expand Down Expand Up @@ -89,7 +89,6 @@ Usage
### Examples + Videos

- useFetch - managed state, request, response, etc. [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-request-response-managed-state-ruyi3?file=/src/index.js) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=_-GujYZFCKI&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=6)
- useFetch - route, path, Provider, etc. [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-with-provider-c78w2) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=JWDL_AVOYT0&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=10)
- useFetch - request/response interceptors [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-provider-requestresponse-interceptors-s1lex) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=3HauoWh0Jts&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=8)
- useFetch - retries, retryOn, retryDelay [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-retryon-retrydelay-s74q9) [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=grE3AX-Q9ss&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=9)
- useFetch - abort, timeout, onAbort, onTimeout [![](https://img.shields.io/badge/video-red.svg)](https://www.youtube.com/watch?v=7SuD3ZOfu7E&list=PLZIwrWkE9rCdUybd8t3tY-mUMvXkCdenW&index=4)
Expand All @@ -101,7 +100,7 @@ Usage
- useFetch - Next.js [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/s/usefetch-in-nextjs-nn9fm)
- useFetch - create-react-app [![](https://img.shields.io/badge/example-blue.svg)](https://codesandbox.io/embed/km04k9k9x5)

<details open><summary><b>Basic Usage (managed state) <code>useFetch</code></b></summary>
<details open><summary><b>Basic Usage Managed State <code>useFetch</code></b></summary>

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.

Expand Down Expand Up @@ -147,20 +146,18 @@ function Todos() {

</details>

<details><summary><b>Basic Usage (auto managed state) <code>useFetch</code></b></summary>
<details open><summary><b>Basic Usage Auto-Managed State <code>useFetch</code></b></summary>

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**
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.

```js
import useFetch from 'use-http'

function Todos() {
// accepts all `fetch` options
const options = {
data: [], // setting default for `data` as array instead of undefined
}

const { loading, error, data } = useFetch('https://example.com/todos', options, []) // onMount (GET by default)
const { loading, error, data } = useFetch('https://example.com/todos', {
// these options accept all native `fetch` options
data: [] // defaults the `data` to an array instead of `undefined`
}, []) // <- this [] means it will fire onMount (GET by default)

return (
<>
Expand All @@ -179,52 +176,15 @@ function Todos() {

</details>


<details open><summary><b>Basic Usage (auto managed state) with <code>Provider</code></b></summary>

```js
import useFetch, { Provider } from 'use-http'

function Todos() {
const { loading, error, data } = useFetch({
path: '/todos',
data: []
}, []) // onMount

return (
<>
{error && 'Error!'}
{loading && 'Loading...'}
{data.map(todo => (
<div key={todo.id}>{todo.title}</div>
)}
</>
)
}

const App = () => (
<Provider url='https://example.com'>
<Todos />
</Provider>
)
```

<!-- TODO: youtube -->
<a target="_blank" rel="noopener noreferrer" href='https://codesandbox.io/s/usefetch-provider-requestresponse-interceptors-s1lex?file=/src/index.js'><img width='150px' height='30px' src='https://codesandbox.io/static/img/play-codesandbox.svg' /></a>
<!-- <a target="_blank" rel="noopener noreferrer" href='XXXXXXX'><img width='150px' height='30px' src='https://github.com/ava/use-http/raw/master/public/watch-youtube-video.png' /></a> -->

</details>

<details open><summary><b>Suspense Mode (auto managed state)</b></summary>
<details open><summary><b>Suspense Mode<sup>(experimental)</sup> Auto-Managed State</b></summary>

Can put `suspense` in 2 places. Either `useFetch` (A) or `Provider` (B).

```js
import useFetch, { Provider } from 'use-http'

function Todos() {
const { data: todos } = useFetch({
path: '/todos',
const { data: todos } = useFetch('/todos', {
data: [],
suspense: true // A. can put `suspense: true` here
}, []) // onMount
Expand All @@ -250,9 +210,9 @@ function App() {

</details>

<details><summary><b>Suspense Mode (managed state)</b></summary>
<details><summary><b>Suspense Mode<sup>(experimental)</sup> Managed State</b></summary>

Can put `suspense` in 2 places. Either `useFetch` (A) or `Provider` (B).
Can put `suspense` in 2 places. Either `useFetch` (A) or `Provider` (B). Suspense mode via managed state is very experimental.

```js
import useFetch, { Provider } from 'use-http'
Expand Down Expand Up @@ -328,8 +288,7 @@ import useFetch, { Provider } from 'use-http'
const Todos = () => {
const [page, setPage] = useState(1)

const { data, loading } = useFetch({
path: `/todos?page=${page}&amountPerPage=15`,
const { data, loading } = useFetch(`/todos?page=${page}&amountPerPage=15`, {
onNewData: (currTodos, newTodos) => [...currTodos, ...newTodos], // appends newly fetched todos
perPage: 15, // stops making more requests if last todos fetched < 15
data: []
Expand Down Expand Up @@ -430,10 +389,7 @@ var {

<details><summary><b>Relative routes <code>useFetch</code></b></summary>

⚠️ `baseUrl` is no longer supported, it is now only `url`
```jsx
var request = useFetch({ url: 'https://example.com' })
// OR
var request = useFetch('https://example.com')

request.post('/todos', {
Expand All @@ -451,17 +407,15 @@ request.post('/todos', {


```jsx
const githubRepos = useFetch({
url: `https://github.com/api/search/repositories?q=`
})
const { get, abort, loading, data: repos } = useFetch('https://github.com/api/search/repositories?q=')

// the line below is not isomorphic, but for simplicity we're using the browsers `encodeURI`
const searchGithubRepos = e => githubRepos.get(encodeURI(e.target.value))
const searchGithubRepos = e => get(encodeURI(e.target.value))

<>
<input onChange={searchGithubRepos} />
<button onClick={githubRepos.abort}>Abort</button>
{githubRepos.loading ? 'Loading...' : githubRepos.data.items.map(repo => (
<button onClick={abort}>Abort</button>
{loading ? 'Loading...' : repos.data.items.map(repo => (
<div key={repo.id}>{repo.name}</div>
))}
</>
Expand Down Expand Up @@ -853,7 +807,6 @@ This is exactly what you would pass to the normal js `fetch`, with a little extr
| `onError` | Runs when the request get's an error. If retrying, it is only called on the last retry attempt. | empty function |
| `onNewData` | Merges the current data with the incoming data. Great for pagination. | `(curr, new) => new` |
| `onTimeout` | Called when the request times out. | empty function |
| `path` | When using a global `url` set in the `Provider`, this is useful for adding onto it | `''` |
| `persist` | Persists data for the duration of `cacheLife`. If `cacheLife` is not set it defaults to 24h. Currently only available in Browser. | `false` |
| `perPage` | Stops making more requests if there is no more data to fetch. (i.e. if we have 25 todos, and the perPage is 10, after fetching 2 times, we will have 20 todos. The last 5 tells us we don't have any more to fetch because it's less than 10) For pagination. | `0` |
| `responseType` | This will determine how the `data` field is set. If you put `json` then it will try to parse it as JSON. If you set it as an array, it will attempt to parse the `response` in the order of the types you put in the array. Read about why we don't put `formData` in the defaults [in the yellow Note part here](https://developer.mozilla.org/en-US/docs/Web/API/Body/formData). | `['json', 'text', 'blob', 'readableStream']` |
Expand All @@ -862,7 +815,6 @@ This is exactly what you would pass to the normal js `fetch`, with a little extr
| `retryOn` | You can retry on certain http status codes or have custom logic to decide whether to retry or not via a function. Make sure `retries > 0` otherwise it won't retry. | `[]` |
| `suspense` | Enables Experimental React Suspense mode. [example](https://codesandbox.io/s/usefetch-suspense-i22wv) | `false` |
| `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**. If set to `0`, it will not timeout except for browser defaults. | `0` |
| `url` | Allows you to set a base path so relative paths can be used for each request :) | empty string |

```jsx
const options = {
Expand Down Expand Up @@ -906,9 +858,6 @@ const options = {
// called when the request times out
onTimeout: () => {},

// if you have a global `url` set up, this is how you can add to it
path: '/path/to/your/api',

// this will tell useFetch not to run the request if the list doesn't haveMore. (pagination)
// i.e. if the last page fetched was < 15, don't run the request again
perPage: 15,
Expand Down Expand Up @@ -957,9 +906,6 @@ const options = {

// amount of time before the request get's canceled/aborted
timeout: 10000,

// used to be `baseUrl`. You can set your URL this way instead of as the 1st argument
url: 'https://example.com',
}

useFetch(options)
Expand Down Expand Up @@ -1001,6 +947,9 @@ If you have feature requests, [submit an issue][1] to let us know what you would
Todos
------

- [ ] prefetching
- [ ] global cache state management
- [ ] optimistic updates
- [ ] `persist` support for React Native
- [ ] better loading state management. When using only 1 useFetch in a component and we use
`Promise.all([get('/todos/1'), get('/todos/2')])` then don't have a loading true,
Expand Down
Loading