【Next.js和訳】Advanced Features/Dynamic Import
この記事について
この記事は、Advanced Features/Dynamic Importの記事を和訳したものです。
記事内で使用する画像は、公式ドキュメント内の画像を引用して使用させていただいております。
ダイナミックインポート
Next.js は、JavaScript の ES2020 dynamic import()
をサポートしています。これを使うと、JavaScript モジュールを動的にインポートし、それらを扱うことができます。また、SSR でも動作します。
次の例では、fuse.js
を使ってファジー検索を実装し、ユーザーが検索入力をした後にのみ、ブラウザにモジュールを動的にロードします。
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>
)
}
ダイナミックインポートは、コードを管理可能なチャンクに分割する別の方法と考えることができます。
React コンポーネントもダイナミックインポートを使用してインポートすることができますが、今回は他の React コンポーネントと同様に動作するようにnext/dynamic
と組み合わせて使用しています。仕組みの詳細については、以下のセクションをチェックしてください。
基本的な使い方
以下の例では、モジュール ../components/hello
がページによって動的に読み込まれます。
import dynamic from "next/dynamic"
const DynamicComponent = dynamic(() => import("../components/hello"))
function Home() {
return (
<div>
<Header />
<DynamicComponent />
<p>HOME PAGE is here!</p>
</div>
)
}
export default Home
DynamicComponent
は、../components/hello
が返すデフォルトのコンポーネントになります。これは通常の React Component のように動作し、通常のように props を渡すことができます。
名前付きエクスポートの場合
ダイナミックコンポーネントがデフォルトのエクスポートでない場合、名前付きのエクスポートも使用できます。モジュール ../components/hello.js
が名前付きエクスポート Hello
を持っているとします:
export function Hello() {
return <p>Hello!</p>
}
Hello
コンポーネントを動的にインポートするには、import()
が返すPromiseから次のようにして返します。
import dynamic from "next/dynamic"
const DynamicComponent = dynamic(() => import("../components/hello").then((mod) => mod.Hello))
function Home() {
return (
<div>
<Header />
<DynamicComponent />
<p>HOME PAGE is here!</p>
</div>
)
}
export default Home
カスタムローディングコンポーネント
オプションのloading
コンポーネントを追加すると、ダイナミックコンポーネントのロード中にローディング状態をレンダリングすることができます。例えば、以下のようになります:
import dynamic from "next/dynamic"
const DynamicComponentWithNoSSR = dynamic(() => import("../components/hello3"), { ssr: false })
function Home() {
return (
<div>
<Header />
<DynamicComponentWithNoSSR />
<p>HOME PAGE is here!</p>
</div>
)
}
export default Home
SSR なしの場合
あるモジュールをサーバーサイドに入れたいとは限らないでしょう。例えば、そのモジュールがブラウザ上でのみ動作するライブラリを含んでいる場合です。
以下の例を見てみましょう。
import dynamic from "next/dynamic"
const DynamicComponentWithNoSSR = dynamic(() => import("../components/hello3"), { ssr: false })
function Home() {
return (
<div>
<Header />
<DynamicComponentWithNoSSR />
<p>HOME PAGE is here!</p>
</div>
)
}
export default Home
サスペンスとは
オプションのsuspense
を使うと、React.lazy
や React 18 の<Suspense>
のように、コンポーネントを遅延ロードすることができます。ただし、このオプションはクライアントサイドまたはfallback
付きのサーバーサイドでのみ動作します。同時モードでの SSR の完全なサポートはまだ進行中です。
import dynamic from "next/dynamic"
const DynamicLazyComponent = dynamic(() => import("../components/hello4"), {
suspense: true,
})
function Home() {
return (
<div>
<Suspense fallback={`loading`}>
<DynamicLazyComponent />
</Suspense>
</div>
)
}
Discussion