Skip to content
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

Release v9.0.0 #151

Merged
merged 122 commits into from
Oct 7, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
a5ec15d
Update upgrade instructions.
ghengeveld Aug 23, 2019
4c0c7c5
Update dependency eslint to v6.2.2 (#89)
renovate[bot] Aug 24, 2019
5d0df23
Change root package name to avoid ambiguity.
ghengeveld Aug 25, 2019
0ef2f6c
Update dependency babel-eslint to v10.0.3 (#90)
renovate[bot] Aug 26, 2019
f5dda65
Update contribution guide.
ghengeveld Aug 26, 2019
9e7dac7
Text wrapping.
ghengeveld Aug 28, 2019
24ea2b0
Clarify behavior when 'initialValue' is set.
ghengeveld Aug 28, 2019
e7f9ab3
Update dependency eslint-plugin-jest to v22.16.0 (#94)
renovate[bot] Aug 29, 2019
4b179bc
Auto detect React version for ESLint.
ghengeveld Aug 30, 2019
bd48e66
Add Discord badge.
ghengeveld Aug 30, 2019
58a98d8
Add brand images.
ghengeveld Aug 30, 2019
be2f03f
Update dependency @storybook/react to v5.2.0-rc.2 (#91)
renovate[bot] Sep 2, 2019
0bd142d
Update dependency eslint to v6.3.0 (#95)
renovate[bot] Sep 2, 2019
202d3e0
Setup Chromatic.
ghengeveld Sep 4, 2019
3159615
Update babel monorepo to v7.6.0 (#106)
renovate[bot] Sep 6, 2019
91a7d88
Update dependency eslint-plugin-jest to v22.17.0 (#101)
renovate[bot] Sep 6, 2019
1e3b57d
Update dependency @testing-library/react to v9.1.4 (#99)
renovate[bot] Sep 6, 2019
8125fbf
Pin dependency storybook-chromatic to 2.2.2 (#100)
renovate[bot] Sep 6, 2019
7552f1a
Add displayName to the createInstance type signature. (#102)
artdent Sep 6, 2019
1797535
Transferred ownership of the repo to async-library.
ghengeveld Sep 6, 2019
ced2ba2
Fix merge error.
ghengeveld Sep 6, 2019
352875a
remove non implemented types (#107)
Khartir Sep 6, 2019
1ea71b6
Add a unit test for the createInstance displayName arg. (#108)
artdent Sep 9, 2019
85ffab0
Update dependency eslint-config-prettier to v6.2.0 (#98)
renovate[bot] Sep 9, 2019
c3fe2cc
Update dependency now to v16.2.0 (#96)
renovate[bot] Sep 9, 2019
d21d7df
updated contribute.md to run examples (#110)
Avi98 Sep 14, 2019
702a32f
Replace occurences of Async.Loading with Async.Pending and isLoading …
ghengeveld Sep 14, 2019
bef2266
Update bootstrap script to include building packages.
ghengeveld Sep 14, 2019
42f68fb
Replace synthetic default imports with star import in ts definit… (#112)
rokoroku Sep 16, 2019
2e41b88
Update Chromatic app code.
ghengeveld Sep 16, 2019
491d7ec
Merge branch 'master' into next
ghengeveld Sep 17, 2019
5b53428
Add delay for Chromatic to avoid flake.
ghengeveld Sep 17, 2019
ff9e875
Add Chromatic badge.
ghengeveld Sep 17, 2019
b9ca8ce
Use the right color for Chromatic.
ghengeveld Sep 17, 2019
2a99f66
Setup CodeSandbox CI.
ghengeveld Sep 18, 2019
62cbfd1
Fix a merge issue.
ghengeveld Sep 18, 2019
d162c3f
Update dependency @storybook/react to v5.2.0-rc.6 (#97)
renovate[bot] Sep 18, 2019
7c926dc
docs: add Khartir as a contributor (#117)
allcontributors[bot] Sep 19, 2019
da64f0c
docs: add phryneas as a contributor (#118)
allcontributors[bot] Sep 19, 2019
e63d58a
docs: add FredKSchott as a contributor (#120)
allcontributors[bot] Sep 19, 2019
7940c5a
docs: add Avi98 as a contributor (#119)
allcontributors[bot] Sep 19, 2019
2bd3875
Update README.md
ghengeveld Sep 19, 2019
b530856
Update README.md
ghengeveld Sep 19, 2019
37a952f
docs: add byCedric as a contributor (#121)
allcontributors[bot] Sep 19, 2019
713d50b
docs: add tomshane as a contributor (#122)
allcontributors[bot] Sep 19, 2019
dba4d2f
docs: add ghengeveld as a contributor (#123)
allcontributors[bot] Sep 19, 2019
a8ab4ba
docs: add philip-peterson as a contributor (#124)
allcontributors[bot] Sep 19, 2019
3dcad77
docs: add sibelius as a contributor (#125)
allcontributors[bot] Sep 19, 2019
a67f736
docs: add jimthedev as a contributor (#126)
allcontributors[bot] Sep 19, 2019
4a1b18c
docs: add msokk as a contributor (#127)
allcontributors[bot] Sep 19, 2019
965601e
docs: add brabeji as a contributor (#128)
allcontributors[bot] Sep 19, 2019
9a709ae
docs: add unorsk as a contributor (#129)
allcontributors[bot] Sep 19, 2019
66d864a
docs: add matthisk as a contributor (#130)
allcontributors[bot] Sep 19, 2019
9306af2
docs: add dhurlburtusa as a contributor (#131)
allcontributors[bot] Sep 19, 2019
a6834b8
docs: add dhurlburtusa as a contributor (#132)
allcontributors[bot] Sep 19, 2019
35d4449
docs: add noelyoo as a contributor (#133)
allcontributors[bot] Sep 19, 2019
61d81ec
docs: add aratcliffe as a contributor (#134)
allcontributors[bot] Sep 19, 2019
c045219
docs: add kentcdodds as a contributor (#135)
allcontributors[bot] Sep 19, 2019
c05ac0b
docs: add noelyoo as a contributor (#136)
allcontributors[bot] Sep 19, 2019
b6db87d
docs: add walter-ind as a contributor (#137)
allcontributors[bot] Sep 19, 2019
7cf04ae
docs: add phryneas as a contributor (#138)
allcontributors[bot] Sep 19, 2019
bdb47b2
docs: add artdent as a contributor (#139)
allcontributors[bot] Sep 19, 2019
2dea878
docs: add Avi98 as a contributor (#140)
allcontributors[bot] Sep 19, 2019
a59c985
docs: add rokoroku as a contributor (#141)
allcontributors[bot] Sep 19, 2019
df67695
Update README.md
ghengeveld Sep 19, 2019
e107a1d
Drop the avatar size and add the badge back.
ghengeveld Sep 19, 2019
95c27d1
Add the All Contributors badge.
ghengeveld Sep 19, 2019
69a13cc
No need to brag.
ghengeveld Sep 19, 2019
b678e3c
docs: add elsangedy as a contributor (#142)
allcontributors[bot] Sep 19, 2019
428256a
Make sure useFetch rejects with an Error type. (#114)
artdent Sep 19, 2019
11d753c
Bump all dependencies. (#147)
ghengeveld Sep 28, 2019
fabbc25
Make sure the promise render prop is always defined (#148)
ghengeveld Sep 28, 2019
3508370
Fix test for promise prop.
ghengeveld Sep 28, 2019
23f8d1e
Use catch instead of then(..., onReject).
ghengeveld Sep 28, 2019
16b9385
Merge branch 'master' into next
ghengeveld Sep 28, 2019
ebe1802
Allow overriding the 'resource' argument of 'fetch' when invokin… (#150)
ghengeveld Sep 28, 2019
a36c8a9
Add upgrade note for v9.
ghengeveld Sep 28, 2019
69c7d08
Lock down all version ranges.
ghengeveld Sep 29, 2019
09d9914
Fix eslint config.
ghengeveld Sep 29, 2019
9faff46
Attempt at fixing CircleCI memory issue.
ghengeveld Sep 29, 2019
3e51b7c
Bump deps.
ghengeveld Sep 29, 2019
11f8996
Update lockfile.
ghengeveld Sep 29, 2019
4cfaa0c
Add experimental Suspense support (#153)
ghengeveld Sep 30, 2019
f3ad45b
Merge branch 'next' into release
ghengeveld Sep 30, 2019
10352c2
Disable propType eslint rule for stories.
ghengeveld Sep 30, 2019
9b05882
Merge branch 'next' into release
ghengeveld Sep 30, 2019
ae4f0fd
Merge branch 'master' into next
ghengeveld Sep 30, 2019
8b8d761
Update dependency now to v16.3.0 (#156)
renovate[bot] Sep 30, 2019
2c769e8
Add CodeFund sponsorship message to README (#144)
Oct 1, 2019
edad9f5
Merge branch 'master' into next
ghengeveld Oct 2, 2019
93c7cbd
Setup gitbook.
ghengeveld Oct 5, 2019
e36cd0f
Fix gitbook config.
ghengeveld Oct 5, 2019
80585db
Use gitbook summary.
ghengeveld Oct 5, 2019
a0567e7
GitBook: [next] 7 pages modified
ghengeveld Oct 5, 2019
fde7e09
Clean up usage examples.
ghengeveld Oct 5, 2019
d3fedaa
Add shortcut links to API docs.
ghengeveld Oct 6, 2019
4c851a4
Move gitbook to docs.
ghengeveld Oct 6, 2019
b6df223
Clean up the readme and docs.
ghengeveld Oct 6, 2019
87dbdef
Fix introduction link.
ghengeveld Oct 6, 2019
86d8051
Restructure docs.
ghengeveld Oct 6, 2019
60b26b0
Place introduction outside the getting started section.
ghengeveld Oct 6, 2019
17496c2
Improve interfaces docs.
ghengeveld Oct 6, 2019
54ce390
Minor improvements.
ghengeveld Oct 6, 2019
00a5820
Fix links.
ghengeveld Oct 6, 2019
fa88098
Fix links.
ghengeveld Oct 6, 2019
3e13ec3
Fix links.
ghengeveld Oct 6, 2019
90b7891
Add createInstance to interfaces.
ghengeveld Oct 6, 2019
3f267a9
Upgrade dependencies and remove the lockfile.
ghengeveld Oct 6, 2019
554b75c
Fix Travis link.
ghengeveld Oct 6, 2019
f6514b8
Minor clarification.
ghengeveld Oct 6, 2019
39d38a5
Make a clear distinction between 'state' and 'options' by avoiding 'p…
ghengeveld Oct 7, 2019
34e2f01
Fix link.
ghengeveld Oct 7, 2019
608f471
Merge branch 'next' into release
ghengeveld Oct 7, 2019
6855a62
Add upgrade docs.
ghengeveld Oct 7, 2019
b629377
Change the way to override 'resource' from useFetch's 'run' function.
ghengeveld Oct 7, 2019
f902546
Avoid memory leaks by using a mock promise.
ghengeveld Oct 7, 2019
9578281
Fix FetchError prototype chain.
ghengeveld Oct 7, 2019
494df62
Avoid using ESLint config override file because CodeFactor doesn't su…
ghengeveld Oct 7, 2019
1223710
Merge branch 'master' into next
ghengeveld Oct 7, 2019
c48f9f4
Merge branch 'next' into release
ghengeveld Oct 7, 2019
2f88009
Make sure neverSettle is an instance of Promise.
ghengeveld Oct 7, 2019
e66dd46
Exclude some impossible to test paths from code coverage.
ghengeveld Oct 7, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Setup gitbook.
  • Loading branch information
ghengeveld committed Oct 5, 2019
commit 93c7cbd0c9e66e11f7cb79cce9da11b1bb4f6e3f
5 changes: 5 additions & 0 deletions .gitbook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
root: ./gitbook/

structure:
readme: introduction.md
summary: _summary.md
32 changes: 32 additions & 0 deletions gitbook/1.introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Introduction

React Async is a utility belt for declarative promise resolution and data fetching. It makes it easy to handle
asynchronous UI states, without assumptions about the shape of your data or the type of request. React Async consists of
a React component and several hooks. You can use it with `fetch`, Axios or other data fetching libraries, even GraphQL.

## Rationale

React Async is different in that it tries to resolve data as close as possible to where it will be used, while using
declarative syntax, using just JSX and native promises. This is in contrast to systems like Redux where you would
configure any data fetching or updates on a higher (application global) level, using a special construct
(actions/reducers).

React Async works well even in larger applications with multiple or nested data dependencies. It encourages loading
data on-demand and in parallel at component level instead of in bulk at the route/page level. It's entirely decoupled
from your routes, so it works well in complex applications that have a dynamic routing model or don't use routes at all.

React Async is promise-based, so you can resolve anything you want, not just `fetch` requests.

## Concurrent React and Suspense

The React team is currently working on a large rewrite called [Concurrent React], previously known as "Async React".
Part of this rewrite is Suspense, which is a generic way for components to suspend rendering while they load data from
a cache. It can render a fallback UI while loading data, much like `<Async.Pending>`.

React Async has no direct relation to Concurrent React. They are conceptually close, but not the same. React Async is
meant to make dealing with asynchronous business logic easier. Concurrent React will make those features have less
impact on performance and usability. When Suspense lands, React Async will make full use of Suspense features. In fact,
you can already **start using React Async right now**, and in a later update, you'll **get Suspense features for free**.
In fact, React Async already has experimental support for Suspense, by passing the `suspense` option.

[concurrent react]: https://github.com/sw-yx/fresh-concurrent-react/blob/master/Intro.md#introduction-what-is-concurrent-react
49 changes: 49 additions & 0 deletions gitbook/2.installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Getting started

You can install `react-async` from npm:

```
npm install --save react-async
```

Or if you're using Yarn:

```
yarn add react-async
```

> This package requires `react` as a peer dependency. Please make sure to install that as well.
> If you want to use the `useAsync` hook, you'll need `react@16.8.0` or later.

## Upgrading

### Upgrade to v8

All standalone helper components were renamed to avoid import naming collision.

- `<Initial>` was renamed to `<IfInitial>`.
- `<Pending>` was renamed to `<IfPending>`.
- `<Fulfilled>` was renamed to `<IfFulfilled>`.
- `<Rejected>` was renamed to `<IfRejected`.
- `<Settled>` was renamed to `<IfSettled>`.

> A [codemod](https://github.com/async-library/react-async/tree/master/codemods) is available to automate the upgrade.

The return type for `run` was changed from `Promise` to `undefined`. You should now use the `promise` prop instead. This
is a manual upgrade. See [`promise`](#promise-1) for details.

### Upgrade to v6

- `<Async.Pending>` was renamed to `<Async.Initial>`.
- Some of the other helpers were also renamed, but the old ones remain as alias.
- Don't forget to deal with any custom instances of `<Async>` when upgrading.

> A [codemod](https://github.com/async-library/react-async/tree/master/codemods) is available to automate the upgrade.

### Upgrade to v4

- `deferFn` now receives an `args` array as the first argument, instead of arguments to `run` being spread at the front
of the arguments list. This enables better interop with TypeScript. You can use destructuring to keep using your
existing variables.
- The shorthand version of `useAsync` now takes the `options` object as optional second argument. This used to be
`initialValue`, but was undocumented and inflexible.
205 changes: 205 additions & 0 deletions gitbook/3.usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# Usage

React Async offers three primary APIs: the `useAsync` hook, the `<Async>` component and the `createInstance`
factory function. Each has its unique benefits and downsides.

## As a hook

The `useAsync` hook (available [from React v16.8.0](https://reactjs.org/hooks)) offers direct access to React Async's
core functionality from within your own function components:

```jsx
import { useAsync } from "react-async"

const loadCustomer = async ({ customerId }, { signal }) => {
const res = await fetch(`/api/customers/${customerId}`, { signal })
if (!res.ok) throw new Error(res)
return res.json()
}

const MyComponent = () => {
const { data, error, isPending } = useAsync({ promiseFn: loadCustomer, customerId: 1 })
if (isPending) return "Loading..."
if (error) return `Something went wrong: ${error.message}`
if (data)
return (
<div>
<strong>Loaded some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)
return null
}
```

> Using [helper components](#with-helper-components) can greatly improve readability of your render functions by not
> having to write all those conditional returns.

Or using the shorthand version:

```jsx
const MyComponent = () => {
const { data, error, isPending } = useAsync(loadCustomer, options)
// ...
}
```

### With `useFetch`

Because fetch is so commonly used with `useAsync`, there's a dedicated `useFetch` hook for it:

```jsx
import { useFetch } from "react-async"

const MyComponent = () => {
const headers = { Accept: "application/json" }
const { data, error, isPending, run } = useFetch("/api/example", { headers }, options)
// This will setup a promiseFn with a fetch request and JSON deserialization.

// you can later call `run` with an optional callback argument to
// last-minute modify the `init` parameter that is passed to `fetch`
function clickHandler() {
run(init => ({
...init,
headers: {
...init.headers,
authentication: "...",
},
}))
}

// alternatively, you can also just use an object that will be spread over `init`.
// please note that this is not deep-merged, so you might override properties present in the
// original `init` parameter
function clickHandler2() {
run({ body: JSON.stringify(formValues) })
}
}
```

`useFetch` takes the same arguments as [fetch] itself, as well as `options` to the underlying `useAsync` hook. The
`options` object takes two special boolean properties: `defer` and `json`. These can be used to switch between
`deferFn` and `promiseFn`, and enable JSON parsing. By default `useFetch` automatically uses `promiseFn` or `deferFn`
based on the request method (`deferFn` for POST / PUT / PATCH / DELETE) and handles JSON parsing if the `Accept` header
is set to `"application/json"`.

[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch

## As a component

The classic interface to React Async. Simply use `<Async>` directly in your JSX component tree, leveraging the render
props pattern:

```jsx
import Async from "react-async"

// Your promiseFn receives all props from Async and an AbortController instance
const loadCustomer = ({ customerId }, { signal }) =>
fetch(`/api/customers/${customerId}`, { signal })
.then(res => (res.ok ? res : Promise.reject(res)))
.then(res => res.json())

const MyComponent = () => (
<Async promiseFn={loadCustomer} customerId={1}>
{({ data, error, isPending }) => {
if (isPending) return "Loading..."
if (error) return `Something went wrong: ${error.message}`
if (data)
return (
<div>
<strong>Loaded some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)
return null
}}
</Async>
)
```

> Using [helper components](#with-helper-components) can greatly improve readability of your render functions by not
> having to write all those conditional returns.

## As a factory

You can also create your own component instances, allowing you to preconfigure them with options such as default
`onResolve` and `onReject` callbacks.

```jsx
import { createInstance } from "react-async"

const loadCustomer = ({ customerId }, { signal }) =>
fetch(`/api/customers/${customerId}`, { signal })
.then(res => (res.ok ? res : Promise.reject(res)))
.then(res => res.json())

// createInstance takes a defaultProps object and a displayName (both optional)
const AsyncCustomer = createInstance({ promiseFn: loadCustomer }, "AsyncCustomer")

const MyComponent = () => (
<AsyncCustomer customerId={1}>
<AsyncCustomer.Fulfilled>{customer => `Hello ${customer.name}`}</AsyncCustomer.Fulfilled>
</AsyncCustomer>
)
```

## With helper components

Several [helper components](#helper-components) are available to improve legibility. They can be used with `useAsync`
by passing in the state, or with `<Async>` by using Context. Each of these components simply enables or disables
rendering of its children based on the current state.

```jsx
import { useAsync, IfPending, IfFulfilled, IfRejected } from "react-async"

const loadCustomer = async ({ customerId }, { signal }) => {
// ...
}

const MyComponent = () => {
const state = useAsync({ promiseFn: loadCustomer, customerId: 1 })
return (
<>
<IfPending state={state}>Loading...</IfPending>
<IfRejected state={state}>{error => `Something went wrong: ${error.message}`}</IfRejected>
<IfFulfilled state={state}>
{data => (
<div>
<strong>Loaded some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)}
</IfFulfilled>
</>
)
}
```

### As compounds to `<Async>`

Each of the helper components are also available as static properties of `<Async>`. In this case you won't have to pass
the state object, instead it will be automatically provided through Context.

```jsx
import Async from "react-async"

const loadCustomer = ({ customerId }, { signal }) =>
fetch(`/api/customers/${customerId}`, { signal })
.then(res => (res.ok ? res : Promise.reject(res)))
.then(res => res.json())

const MyComponent = () => (
<Async promiseFn={loadCustomer} customerId={1}>
<Async.Pending>Loading...</Async.Pending>
<Async.Fulfilled>
{data => (
<div>
<strong>Loaded some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)}
</Async.Fulfilled>
<Async.Rejected>{error => `Something went wrong: ${error.message}`}</Async.Rejected>
</Async>
)
```
Loading