Skip to content

Commit

Permalink
Update dynamic-import docs (#16803)
Browse files Browse the repository at this point in the history
Goals of this PR:

- Explain `import()` first without mentioning `next/dynamic`, because `next/dynamic` in our API and **Dynamic Import** is a ES feature. This should avoid a common confusion in our users thinking that one can't be used without the other.
- Mention how `next/dynamic` can be used with **Dynamic Imports** to load react components.
- Updated example to include fuzzy search using a dynamic import.

Potential change: Leave the page to be about `import()` and move `next/dynamic` to the API reference (alongside `next/link`, `next/router`, etc.)

Closes #16299
Closes #15711
  • Loading branch information
lfades authored Sep 5, 2020
1 parent a7a6aa5 commit b5cf3e4
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
36 changes: 34 additions & 2 deletions docs/advanced-features/dynamic-import.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,49 @@ description: Dynamically import JavaScript modules and React Components and spli

# Dynamic Import

<details>
<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-dynamic-import">Dynamic Import</a></li>
</ul>
</details>

Next.js supports ES2020 [dynamic `import()`](https://github.com/tc39/proposal-dynamic-import) for JavaScript. With it you can import JavaScript modules (inc. React Components) dynamically and work with them. They also work with SSR.
Next.js supports ES2020 [dynamic `import()`](https://github.com/tc39/proposal-dynamic-import) for JavaScript. With it you can import JavaScript modules dynamically and work with them. They also work with SSR.

In the following example, we implement fuzzy search using `fuse.js` and only load the module dynamically in the browser after the user types in the search input:

```jsx
import { useState } from 'react'

const names = ['Tim', 'Joe', 'Bel', 'Max', 'Lee']

export default function Page() {
const [results, setResults] = useState()

return (
<div>
<input
type="text"
placeholder="Search"
onChange={async (e) => {
const { value } = e.currentTarget
// Dynamically load fuse.js
const Fuse = (await import('fuse.js')).default
const fuse = new Fuse(names)

setResults(fuse.search(value))
}}
/>
<pre>Results: {JSON.stringify(results, null, 2)}</pre>
</div>
)
}
```

You can think of dynamic imports as another way to split your code into manageable chunks.

React components can also be imported using dynamic imports, but in this case we use it in conjunction with `next/dynamic` to make sure it works just like any other React Component. Check out the sections below for more details on how it works.

## Basic usage

In the following example, the module `../components/hello` will be dynamically loaded by the page:
Expand Down
2 changes: 1 addition & 1 deletion examples/with-dynamic-import/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
"start": "next start"
},
"dependencies": {
"fuse.js": "6.4.1",
"next": "latest",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"author": "",
"license": "MIT"
}
20 changes: 20 additions & 0 deletions examples/with-dynamic-import/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ const DynamicComponent4 = dynamic(() => import('../components/hello4'))

const DynamicComponent5 = dynamic(() => import('../components/hello5'))

const names = ['Tim', 'Joe', 'Bel', 'Max', 'Lee']

const IndexPage = () => {
const [showMore, setShowMore] = useState(false)
const [falsyField] = useState(false)
const [results, setResults] = useState()

return (
<div>
Expand All @@ -41,6 +44,23 @@ const IndexPage = () => {
{/* Load on demand */}
{showMore && <DynamicComponent5 />}
<button onClick={() => setShowMore(!showMore)}>Toggle Show More</button>

{/* Load library on demand */}
<div style={{ marginTop: '1rem' }}>
<input
type="text"
placeholder="Search"
onChange={async (e) => {
const { value } = e.currentTarget
// Dynamically load fuse.js
const Fuse = (await import('fuse.js')).default
const fuse = new Fuse(names)

setResults(fuse.search(value))
}}
/>
<pre>Results: {JSON.stringify(results, null, 2)}</pre>
</div>
</div>
)
}
Expand Down

0 comments on commit b5cf3e4

Please sign in to comment.