Skip to content

Commit

Permalink
1st argument changes, remove "path" and "url" options, bug fixes (#251)
Browse files Browse the repository at this point in the history
* first go

* cleanup

* cleanup

* updating documentation

* added docs for conditional auto-managed state

* cleanup

* docs cleanup

* cleanup

* link to contributions.md

* bettering docs

* added `skip` option, `skip` tests, fixed bug with `responseType`

* forgot to hit save

* tests for not overwriting every instance of useFetch global options

* tests for path and route without a /

* cache cleanup

* updating docs

* removing conditional auto-managed state from this PR

* forgot to remove skip from types.ts
  • Loading branch information
alex-cory authored Apr 23, 2020
1 parent f7cc214 commit 8c8937d
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 441 deletions.
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://api.github.com/search/repositories?q=`
})
const { get, abort, loading, data: repos } = useFetch('https://api.github.com/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

0 comments on commit 8c8937d

Please sign in to comment.