Skip to content

Commit 89caadd

Browse files
committed
Updates docs.
1 parent 5ee4759 commit 89caadd

File tree

1 file changed

+71
-84
lines changed

1 file changed

+71
-84
lines changed

README.md

+71-84
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ Resolve components asynchronously, with support for code splitting and advanced
1010
[![Codecov](https://img.shields.io/codecov/c/github/ctrlplusb/react-async-component.svg?style=flat-square)](https://codecov.io/github/ctrlplusb/react-async-component)
1111

1212
```jsx
13-
const Product = asyncComponent({
14-
resolve: () => System.import('./AsyncProduct'),
13+
const AsyncProduct = asyncComponent({
14+
resolve: () => System.import('./Product'),
1515
LoadingComponent: ({ productId }) => <div>Loading {productId}</div>, // Optional
1616
ErrorComponent: ({ error }) => <div>{error.message}</div> // Optional
1717
});
1818

19-
<Product productId={1} /> // 🚀
19+
<AsyncProduct productId={1} /> // 🚀
2020
```
2121

2222
## TOCs
@@ -45,60 +45,50 @@ This library does not require that you use either Webpack or Babel. Instead it
4545

4646
## Usage
4747

48-
When creating your asynchronous components I recommend that you use the following folder/file structure:
48+
Imagine you had the following `Product` component:
4949

50-
```
51-
|- components
52-
|- Product
53-
|- index.js
54-
|- AsyncProduct.js
50+
```jsx
51+
export default function Product({ id }) {
52+
return <div>Product {id}</div>
53+
}
5554
```
5655

57-
__`./components/Product/index.js`__:
56+
To make this asynchronous create a new file that wraps it with `asyncComponent`, like so:
5857

59-
```js
58+
```jsx
6059
import { asyncComponent } from 'react-async-component';
6160

62-
// Create an async component👇
6361
export default asyncComponent({
64-
resolve: () => System.import('./AsyncProduct')
65-
// That resolves to 👆
62+
resolve: () => System.import('./Product')
6663
});
6764
```
6865

69-
__`./components/Product/AsyncProduct.js`__
70-
71-
```jsx
72-
import React from 'react';
66+
I recommend that you use the following folder/file structure:
7367

74-
export default function Product({ productId }) {
75-
return <div>You are viewing product {productId}</div>;
76-
}
68+
```
69+
|- components
70+
|- AsyncProduct
71+
|- index.js // contains asyncComponent
72+
|- Product.js // The component you want resolved asynchronously
7773
```
7874

79-
Now, you can simply import `Product` anywhere in your application and use it exactly as you would any other component.
75+
Now, you can simply import `AsyncProduct` anywhere in your application and use it exactly as you would any other component.
8076

8177
For example:
8278

8379
```jsx
84-
import React from 'react';
85-
import Product from './components/Product';
86-
87-
const MyApp = () => (
88-
<div>
89-
<h1>Welcome to My App</h1>
90-
// 👇 Use as "normal"
91-
<Product productId={1337} />
92-
</div>
93-
);
94-
95-
export default MyApp;
80+
import AsyncProduct from './components/AsyncProduct'
81+
82+
export default function MyApp() {
83+
return (
84+
<div>
85+
<h1>Welcome to My App</h1>
86+
<AsyncProduct id={1337} />
87+
</div>
88+
)
89+
}
9690
```
9791

98-
🚀
99-
100-
You have a lot more power than is shown here. Be sure to check out the [`API`](#api) for more.
101-
10292
## API
10393

10494
### `asyncComponent(config)`
@@ -117,7 +107,7 @@ The asynchronous component factory. Config goes in, an asynchronous component co
117107
- __`'render'`__ - Your asynchronous component will be resolved and rendered on the server. It's children will
118108
be checked to see if there are any nested asynchronous component instances, which will then be processed based on the `serverMode` value that was associated with them.
119109
- __`'defer'`__ - Your asynchronous component will _not_ be rendered on the server, instead deferring rendering to the client/browser.
120-
- __`'boundary'`__ - Your asynchronous component will be resolved and rendered on the server. However, if it has a nested asynchronous component instance within it's children that component will be ignored and treated as being deferred for rendering in the client/browser instead.
110+
- __`'boundary'`__ - Your asynchronous component will be resolved and rendered on the server. However, if it has a nested asynchronous component instance within it's children that component will be ignored and treated as being deferred for rendering in the client/browser instead (it's serverMode will be ignored).
121111
We highly recommend that you consider using `defer` as much as you can.
122112

123113
#### Returns
@@ -130,40 +120,35 @@ A React Component.
130120

131121
```jsx
132122
export default asyncComponent({
133-
resolve: () => import('./AsyncProduct'),
134-
LoadingComponent: ({ productId }) => <div>Loading product {productId}</div>
135-
});
123+
resolve: () => import('./Product'),
124+
LoadingComponent: ({ id }) => <div>Loading product {id}</div>
125+
})
136126
```
137127

138128
##### `ErrorComponent`
139129

140130
```jsx
141131
export default asyncComponent({
142-
resolve: () => import('./AsyncProduct'),
143-
LoadingComponent: ({ productId }) => <div>Loading product {productId}</div>
144-
});
132+
resolve: () => import('./Product'),
133+
ErrorComponent: ({ error }) => <div>{error.message}</div>
134+
})
145135
```
146136

147-
##### Webpack `require.ensure` Code Splitting API
137+
##### Named chunks
148138

149139
```jsx
150140
export default asyncComponent({
151141
resolve: () => new Promise(resolve =>
152-
require.ensure([], (require) => {
153-
resolve(require('./components/Product'));
154-
});
142+
// Webpack's code splitting API w/naming
143+
require.ensure(
144+
[],
145+
(require) => {
146+
resolve(require('./Product'));
147+
},
148+
'ChunkName'
149+
)
155150
)
156-
});
157-
```
158-
159-
##### Webpack `import` / `System.import` Code Splitting API
160-
161-
Note: `System.import` is considered deprecated and will be replaced with `import`, but for now they can be used interchangeably (you may need a Babel plugin for the `import` syntax).
162-
163-
```jsx
164-
export default asyncComponent({
165-
resolve: () => System.import('./components/Product')
166-
});
151+
})
167152
```
168153

169154
### `<AsyncComponentProvider />`
@@ -177,7 +162,7 @@ Currently only useful when building server side rendering applications. Wraps yo
177162

178163
### `createAsyncContext()`
179164

180-
Creates an asynchronous context that can be used by the `<AsyncComponentProvider />`. The context is an object that exposes the following properties to you:
165+
Creates an asynchronous context for use by the `<AsyncComponentProvider />`. The context is an object that exposes the following properties to you:
181166

182167
- `getState()` (_() => Object_) : A function that when executed gets the current state of the `<AsyncComponentProvider />`. i.e. which async components resolved / failed to resolve etc. This is especially useful for server sider rendering applications where you need to provide the server rendered state to the client instance in order to ensure the required asynchronous component instances are resolved prior to render.
183168

@@ -200,32 +185,33 @@ npm install react-async-bootstrapper
200185
Now, let's configure the "server" side. You could use a similar `express` (or other HTTP server) middleware configuration:
201186

202187
```jsx
203-
import React from 'react';
204-
import { AsyncComponentProvider, createAsyncContext } from 'react-async-component'; // 👈
205-
import asyncBootstrapper from 'react-async-bootstrapper'; // 👈
206-
import { renderToString } from 'react-dom/server';
207-
import serialize from 'serialize-javascript';
208-
import MyApp from './shared/components/MyApp';
188+
import React from 'react'
189+
import { renderToString } from 'react-dom/server'
190+
import { AsyncComponentProvider, createAsyncContext } from 'react-async-component' // 👈
191+
import asyncBootstrapper from 'react-async-bootstrapper' // 👈
192+
import serialize from 'serialize-javascript'
193+
194+
import MyApp from './shared/components/MyApp'
209195

210196
export default function expressMiddleware(req, res, next) {
211197
// Create the async context for our provider, this grants
212198
// 👇 us the ability to tap into the state to send back to the client.
213-
const asyncContext = createAsyncContext();
199+
const asyncContext = createAsyncContext()
214200

215201
// 👇 Ensure you wrap your application with the provider.
216202
const app = (
217203
<AsyncComponentProvider asyncContext={asyncContext}>
218204
<MyApp />
219205
</AsyncComponentProvider>
220-
);
206+
)
221207

222208
// 👇 This makes sure we "bootstrap" resolve any async components prior to rendering
223209
asyncBootstrapper(app).then(() => {
224-
// It's now safe to render 👇
225-
const appString = renderToString(app);
210+
// We can now render our app 👇
211+
const appString = renderToString(app)
226212

227213
// 👇 Get the async component state.
228-
const asyncState = asyncContext.getState();
214+
const asyncState = asyncContext.getState()
229215

230216
const html = `
231217
<html>
@@ -239,27 +225,28 @@ export default function expressMiddleware(req, res, next) {
239225
window.ASYNC_COMPONENTS_STATE = ${serialize(asyncState)}
240226
</script>
241227
</body>
242-
</html>`;
243-
res.send(html);
244-
});
228+
</html>`
229+
230+
res.send(html)
231+
})
245232
}
246233
```
247234

248235
Then on the "client" side you would do the following:
249236

250237
```jsx
251-
import React from 'react';
252-
import { render } from 'react-dom';
253-
import { AsyncComponentProvider, createAsyncContext } from 'react-async-component'; // 👈
254-
import asyncBootstrapper from 'react-async-bootstrapper'; // 👈
255-
import MyApp from './components/MyApp';
238+
import React from 'react'
239+
import { render } from 'react-dom'
240+
import { AsyncComponentProvider, createAsyncContext } from 'react-async-component' // 👈
241+
import asyncBootstrapper from 'react-async-bootstrapper' // 👈
242+
import MyApp from './components/MyApp'
256243

257244
// 👇 Get any "rehydrate" state sent back by the server
258-
const rehydrateState = window.ASYNC_COMPONENTS_STATE;
245+
const rehydrateState = window.ASYNC_COMPONENTS_STATE
259246

260247
// Create an async context so that state can be tracked
261248
// 👇 across the bootstrapping and rendering process.
262-
const asyncContext = createAsyncContext();
249+
const asyncContext = createAsyncContext()
263250

264251
// Ensure you wrap your application with the provider,
265252
// 👇 and pass in the rehydrateState.
@@ -270,14 +257,14 @@ const app = (
270257
>
271258
<MyApp />
272259
</AsyncComponentProvider>
273-
);
260+
)
274261

275262
// We run the bootstrapper again, which in this context will
276263
// ensure that all components specified by the rehydrateState
277264
// 👇 will be resolved prior to render.
278265
asyncBootstrapper(app).then(() => {
279266
// 👇 Render the app
280-
render(app, document.getElementById('app'));
267+
render(app, document.getElementById('app'))
281268
});
282269
```
283270

0 commit comments

Comments
 (0)