LoginSignup
4
2

More than 5 years have passed since last update.

ローディングコンポーネントのラップ

Last updated at Posted at 2017-10-19

よくあるパターンとして、3項間演算子を使った以下のようなパターンがあります。

this.state.isLoading ? <Loading /> : (
  <div>
    <div>
      <MyComponent1 />
    </div>
    <div>
      <MyComponent2 />
    </div>
    <div>
      <MyComponent3 />
    </div>
    <div>
      <MyComponent4 />
    </div>
  </div>
)

しかし、どちらを先に書くか?等の不要な判断が入るスキマが残っています。
例えば、以下の場合はローディング中にMyCompコンポーネントが表示されてしまうでしょう。

this.state.isLoading ? <MyComp /> : <Loading />

このような場合、ローディングを抽象したコンポーネントを用意してあげると便利です。
MyComponentは必ずローディング後にレンダリングされることが保証されます。

<SwitchLoading isLoading={this.state.isLoading}>
    <MyComponent />
</SwitchLoading>

やり方は色々ありますが、シンプルにこんな感じで用意して上げればいいと思います。
ここでは、更にMaybeコンポーネントを用意しています。
もちろん、flowを使わない理由はないですから、flowで型付けを行います。

// @flow
import * as React from 'react'

class Maybe extends React.Component<{
  flag: boolean,
  children?: React.Node,
  else: React.Node,
}> {
  render() {
    const { props } = this

    return props.flag ? props.children : props.else
  }
}

const Loading = () => <div>Loading...</div>

class SwitchLoading extends React.Component<{
  isLoading: boolean,
  children?: React.Node,
}> {
  render() {
    const { props } = this

    return (
      <Maybe flag={props.isLoading} else={<Loading />}>
        {props.children}
      </Maybe>
    )
  }
}

const MyComponent = () => <h2>Hello World</h2>

class App extends React.Component<{}, { isLoading: boolean }> {
  state = { isLoading: false }

  componentDidMount() {
    setTimeout(() => {
      this.finishLoading()
    }, 2000)
  }

  finishLoading = () => {
    this.setState({ isLoading: true })
  }

  render() {
    const { state } = this

    return (
      <div className="App">
        <SwitchLoading isLoading={state.isLoading}>
          <MyComponent />
        </SwitchLoading>
      </div>
    )
  }
}

export default App

🤔

VS HoC

withLoadingのようなHoCを用意してあげてもいいです。
が、しかし、HoCは便利な反面、複雑で厄介です。
個人的にはパフォーマンス上の理由がない限り、自分でHoCを作成するのは避けます。
どちらかと言えば、コントロール可能なコンポーネントを作る場合、Comp as Funcスタイル(react-motion等)か、レンダラーpropスタイルを使う方が単純で便利だと思います。

4
2
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
4
2