Reactコンポーネントでのローディング、空、エラー状態のレンダリング処理
2018年3月30日2分で読める

Reactコンポーネントでのローディング、空、エラー状態のレンダリング処理

この記事はAIによって翻訳されたため、不正確な場合があります。

免責聲明: このブログ記事の翻訳はAIによって生成されました。翻訳の正確性について保証はありません。重要な情報については、元の記事をご参照ください。

より良いコンポーネント状態表示 = より幸せなユーザー。

全体像

React開発では、データ駆動型コンポーネントの異なる状態を処理する問題によく直面します。ほとんどの場合、これらの状態には以下が含まれます:

  • 理想的な状態。コンポーネントのハッピーパス、すべてが順調です。
  • ローディング状態。コンポーネントがローディング中であることを示す何かを表示します。
  • エラー状態。何かが間違っていることをコンポーネントが表示します。
  • 空の状態。コンポーネントが空であることを示す何かを表示します。

これらのコンポーネントでは、コンポーネントの状態に基づいてユーザーに適切なヒントを表示したいと思います。コードは以下のようになるかもしれません:

container.js

import MyComponent from 'path/to/my/component'
import ErrorHint from 'path/to/error/hint'
import LoadingSpinner from 'path/to/loading/spinner'
import EmptyHint from 'path/to/empty/hint'
class Container extends React.Component {
  render() {
    return (
      // ...
      {
        isComponentError
        ? <ErrorHint />
        : isLoading
          ? <LoadingSpinner />
          : data.length > 0
            ? <MyComponent data={ data } />
            : <EmptyHint />
      }
      // ...
    )
  }
}

問題点

上記のコードは理想的ではありません。なぜなら:

  1. ネストした三項演算子。この種のロジックを実装するコンポーネントがいくつかある場合、一目で理解するのは簡単ではありません。
  2. ロジックの分散。この種の類似したロジックは一般化され、コードベース全体に分散させる代わりに単一の場所で処理できます。
  3. 冗長なインポート<ErrorHint /><LoadingSpinner /><EmptyHint />がプロジェクト全体で同じである場合でも、使用される場所すべてにそれらをインポートする必要があります。これによりコードがより冗長になります。
  4. 低い結合度<ErrorHint /><LoadingSpinner /><EmptyHint />がコンポーネント特有のものである場合、より高い結合度のためにcontainer.jsではなくcomponent.jsに配置されるべきです。

これらの問題に対処するために、プロバイダーパターンが良い解決策だと思います。プロバイダーはグローバルなローディング、空、エラーコンポーネントを提供し、高階コンポーネントを使用してレンダリングロジックを実装したいコンポーネントをラップします。以下のように:

index.js

<RenderCtrlProvider
  ErrorComponent={() => <div>default error hint</div>}
  EmptyComponent={() => <div>default empty hint</div>}
  LoadingComponent={() => <div>default loading hint</div>}
>
  <YourApp />
</RenderCtrlProvider>

YourComponent.js

class YourComponent extends Component {
  //...
}
export default withRenderCtrl(YourComponent, {
  // このコンポーネント用のカスタマイズされたローディング
  LoadingComponent: () => <div>I am loading</div>,
})

container.js

class Container extends Component {
  // ...
  render() {
    return (
      // ...
      <YourComponent
        isError={isComponentError}
        isLoading={isLoading}
        isDataReady={data.length > 0} // またはデータが準備できていることを示す他のロジック
        // "YourComponent"の他のprops...
      />
      // ...
    )
  }
}

npmパッケージ

react-render-ctrlは上記で言及した問題を軽減します。これは以下のレンダリングロジックに基づいてパターンを実装します:

Reactコンポーネント状態フロー グレーの背景の四角形はコンポーネントです

実装の詳細はプロジェクトsrcフォルダで確認できます。

プロジェクト全体でコンポーネントの異なる状態を処理する必要がある場合は、試してみてください :)

結論

プロバイダーパターンと高階コンポーネントは、異なるUI状態での作業を簡素化するために、コンポーネントレンダリングロジックがどのようになるべきかのインターフェースを提供します。レンダリングフローロジックをより柔軟で一般的にするための異なるアイデアがある場合は、私と共有してください。ありがとうございます!