reactコンポーネントのいくつかのモード

5623 ワード

React Component Patterns
有状態構成要素x無状態構成要素、容器構成要素x展示構成要素、高次構成要素x Render Callbacks(Function as Child Component)
Reactを使用してからもうしばらく経ちました.React-Facebookライブラリは、JSを使用してユーザーインタフェースを構築しています.本稿では,これまでの実践で学んだいくつかのモデルを総括するとともに,奇妙なコンポーネントの世界に踏み込む開発者を助けることを望んでいる.
状態有り組立体X状態無し組立体
Webサービスに静的と動的の区別があるように,Reactコンポーネントにも状態と無状態の区別がある.「ステータスコンポーネントあり」(Status Component)--アプリケーション内のコンポーネントは、自身のステータスを持ち、操作することができます.「ステータスコンポーネントなし」(No Status Component)--アトリビュートのみを受信して効果を表示します.
プロパティのみで制御される単純なステータスレスコンポーネント:
const Button = props => (
  
);

カウント機能付きボタンコンポーネント(上のButtonコンポーネントを多重化)
class ButtonCounter extends React.Component {
  constructor() {
    super()
    this.state = { clicks: 0 }
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
    this.setState({ clicks: this.state.clicks + 1 })
  }

  render() {
    return (
      

正如上面两个 Demo 所示,第二个组件的 constructor 具有状态的定义,第一个组件只是单纯地渲染属性文字。有状态组件和无状态组件的划分看起来非常简单,但是它对于组件复用具有重大意义。

容器组件 X 展示组件

当组件需要获取外部数据时,我们又可以将组件划分为两种新的类型。容器组件负责获取数据,它常常是超出了React范畴的,如使用 Redux 或 Relay 进行了绑定。对比而言,展示型组件不依赖于程序其他部分,它只和自身状态或属性有关。下面我们实现一个用户列表的展示组件:

const UserList = props =>
  
    {props.users.map(u => (
  • {u.name} — {u.age} years old
  • ))}

コンテナコンポーネントは、ユーザー・リストの表示を更新するために使用できます.
class UserListContainer extends React.Component {
  constructor() {
    super()
    this.state = { users: [] }
  }

  componentDidMount() {
    fetchUsers(users => this.setState({ users }))
  }

  render() {
    return 
  }
}

この分類は、データ取得とレンダリングの論理を分離し、ユーザリストコンポーネントを多重化することができる.
このモードの詳細については、awesome article from Dan Abramovが正確に説明しています.
高次コンポーネント--HOCs
コンポーネントロジックを多重化したい場合は、高次コンポーネントが便利です.「上位コンポーネント」--コンポーネントをパラメータとして、新しいコンポーネントに戻すJS です.
拡張可能なメニューコンポーネントを構築する必要があるとします.ユーザーがクリックすると、非表示のサブコンポーネントの内容が表示されます.これにより、次のような高度なコンポーネントを使用して実装できます.
function makeToggleable(Clickable) {
  return class extends React.Component {
    constructor() {
      super()
      this.toggle = this.toggle.bind(this)
      this.state = { show: false }
    }

    toggle() {
      this.setState(prevState => ({ show: !prevState.show }))
    }

    render() {
      return (
        
{this.state.show && this.props.children}
) } } }

この方法はES 7装飾文法を用いてToggleableMenuコンポーネントに論理を適用することを可能にする.
@makeToggleable
class ToggleableMenu extends React.Component {
  render() {
    return (
      

{this.props.title}

) } }

これで、ToggleableMenuコンポーネントに任意のサブコンポーネントを渡すことができます.
class Menu extends React.Component {
  render() {
    return (
      

Some content

Another content

More content

) } }

Reduxのconnect関数やReact RouterのwithRouter関数に詳しい場合は、すでに上位コンポーネントを使用しています.
レンダーコールバック--RenderCallbacks(Function as Child Components)
もう一つのハイエンドの多重コンポーネント論理の方法は、関数をコンポーネントとするpropsである.children、この方法はFunction as Child Componentsとも呼ばれる. を使用して、上記の拡張可能なMenuを再実現します.
class Toggleable extends React.Component {
  constructor() {
    super()
    this.toggle = this.toggle.bind(this)
    this.state = { show: false }
  }

  toggle() {
    this.setState(prevState => ({ show: !prevState.show }))
  }

  render() {
    return this.props.children(this.state.show, this.toggle)
  }
}

これで、関数をコンポーネントの子として渡すことができます.
  
    {(show, onClick) => (
      

{props.title}

{show && props.children}
)}

上記のコードは、関数を として使用していますが、上記の論理を多重化するには、変換論理の新しいコンポーネントを作成する必要があります.
const ToggleableMenu = props =>
  
    {(show, onClick) => (
      

{props.title}

{show && props.children}
)}

我々がRender Callbacksを用いて実現した拡張可能なMenuコンポーネントは以下の通りである.
class Menu extends React.Component {
  render() {
    return (
      

Some content

Another content

More content

) } }

Render Callbacksと高次関数は私たちのコンポーネントをより柔軟にし、把握し、適応するのは一定の難易度があり、繰り返し学習と消化が必要です.
本人の能力に限りがありますので、漏れがあれば、ご指摘ください.
【開発環境推奨】Cloud Studioはブラウザベースの集積型開発環境であり、HTML 5、PHP、Python、Java、Ruby、C/C+、.NETウィジェットなど、プログラミング言語の大部分をサポートしている.インストールプログラムをダウンロードすることなく、開発環境をワンタッチで切り替えることができる.Cloud Studioは完全なLinux環境を提供し、カスタムドメイン名指向、動的コンピューティングリソース調整をサポートする全体的に、さまざまなアプリケーションの開発コンパイルと導入を完了することができます.