0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React 遅延読み込みコンポーネントについて (<Suspense>タグ, lazy)

Last updated at Posted at 2024-09-26

遅延コンポーネントを表示しようとしたらエラーになった。

🆘 エラーになった時のコード

App.js
import { lazy, Suspense } from 'react';
import './App.css';

const App = () => {
  const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
  const LazyImage = lazy(() => sleep(2000).then(() => import("./LazyImage")));

  return (
    <Suspense fallback={<p>Now Loading...</p>}>
        <LazyImage />
    </Suspense>
  );
};

export default App;
LazyImage.jsx
export const LazyImage = () => {
    return (
        <img src="https://m.media-amazon.com/images/I/61UydAS35JL.jpg" />
    );
};

📞 エラーの内容

Error
Element type is invalid. Received a promise that resolves to: undefined. Lazy element type must resolve to a class or function.

とりあえず英語が読めないので翻訳↓↓

エラー
要素タイプが無効です。undefinedに解決するプロミスを受け取りました。Lazy 要素型はクラスまたは関数に解決する必要があります。

とのことです。
日本語も読めないので何を言っているのか全く分かりません!!

🚑 結論

こちらのおかげで解決しました!
https://github.com/fuse-box/fuse-box/issues/1646#issuecomment-979481455

引用

You must export default the foo file component

翻訳 ↓↓ (別に翻訳しなくても読めるけどね😉)

fooファイルコンポーネントをデフォルトでエクスポートする必要があります

とのことなので、自分の実装コードでfooファイルに該当する LazyImage.jsxファイルを下記のように修正しました。

LazyImage.jsx
const LazyImage = () => {
    return (
        <img src="https://m.media-amazon.com/images/I/61UydAS35JL.jpg" />
    );
};

export default LazyImage;

これで解決です!

👐 余談

LazyImage をデフォルトエクスポートせずに普通に importして使う場合下記のように {} をつけるじゃないですか。

import { LazyImage } from './LazyImage';

ということで思ったんです、デフォルトエクスポートをしない場合は

const LazyImage = lazy(() => sleep(2000).then(() => import("./LazyImage")));

この部分のコードを

const { LazyImage } = lazy(() => sleep(2000).then(() => import("./LazyImage")));

このようにしたらできるんじゃないかと!
まぁできなかったんですけどね😉
もしかしたら同じことが気になった方もいるかなと思ったので一応補足でした。

余談2

ちなみに遅延コンポーネントに使用する際は必ずデフォルトエクスポートで定義する必要がある。というのも変な気がするなと思ったのでデフォルトエクスポートせずにやる方法もあるのか調べてみたところ下記のコードでも可能なようです。(試しましたができました)

const LazyImage = lazy(() => sleep(2000).then(() => import("./LazyImage").then((module) => ({ default: module.LazyImage }))));

この部分がデフォルトエクスポートに変換をするコードのようです。
https://zenn.dev/bmth/articles/react-lazily#%E5%80%8B%E5%88%A5%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95

import("./foo").then((module) => ({ default: module.SomeComponent }))

デフォルトエクスポートに変換をする。 という挙動について気になることがありますが長くなるので一旦別で調べたいと思います。

まとめ

勉強して1週間経ってないので考え方自体がずれているところがあるかも知れませんが許してください!
まだ何も分かりませんが楽しんで勉強していきたいと思います🫠

それにしても記事を書くのって難しい・・・
僕のお師匠様の言語化能力や疑問を網羅的に調べる能力の高さが改めて身に染みます。。
⛩️🙏

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?