2016-07-08 2 views
0

私はReactJSを学んで使用しています。多数のスレッドやブログの投稿を読み終えた後、私はReactJSのコンポーネント間で効果的なコミュニケーションを取ることと混同しています。親で完全な再レンダリングを行わずに2つの子コンポーネント間の通信を行います

私は親コンポーネント "A"を持っていて、多くの子コンポーネント "a"、 "b"、 "c"、 "d"、 "e"などを持っているとしましょう。私は "b"コンポーネントを再レンダリングしたい。

"a"と "b"は同じ親を持つので、この2つの間の通信媒体として親自体を使用することができます。しかし、ここで問題となるのは、親を通信媒体として使用して状態を変更し、再レンダリングをトリガーすると、すべてのコンポーネント "a"、 "c"、 "d"、 "e"私がそれを好きではない代わりに、 "b"コンポーネントだけを強制的に再レン​​ダリングしたいのです。

これは可能ですか?どうすればこれを達成できますか?基本的には、パフォーマンス上の理由からこれを実行したいと考えています。

+1

フラックス/ Reduxの通信にイベントバスのいくつかの種類を使用します。だから "a"はバスにメッセージを掲示し、気になる人(あなたの場合は "b")がそれに応答します。他は変わらない。あなたはFlux/Reduxを使うことができます(とにかく良い練習とみなされます)。あるいは、自分でバスを実装することもできます。バスはReactの[context](https://facebook.github.io/react/docs/context.html)で共有することができます。 –

+1

Reduxを試してみることを強くお勧めします。 「純粋な」リアクションはあなたが投稿したもののような理由で、実世界のアプリでかなり速く/面倒なことになります。 –

答えて

1

はそれを行うための一つの方法がありますが、...

JavaScriptが速い場合して反応和解アルゴリズムも非常に高速です。 ReactはDOMを再レンダリングしません。他のコンポーネントに変更があるかどうかをチェックし、存在する場合にのみ適用します。

あなたが望むものを作ることができます。そのためには、レンダリングの前に呼び出されるshouldComponentUpdate関数があります。したがって、あなたの子コンポーネントのためにこの関数を実装すると、それらは再レンダリングされません。ただし、実際にパフォーマンスに問題がある場合にのみ、この機能を使用することをお勧めします。

子コンポーネントが単純でオブジェクトの深いツリーがない場合は、shallow compareヘルパー機能を使用できます。将来はすべてデフォルトでpureのコンポーネントに含まれる可能性があります。

0

プレーンリアクトを使用するのは完全に可能です。あなたの親コンポーネントはコンテナとして動作し、その子の小道具に対応する状態を保持する必要があります。子の1つが更新をトリガーすると、shouldComponentUpdateメソッドを実装すると、他の子は再レンダリングされません。ここでは作業中のスニペットです。最初のリストの項目の1つをチェック/選択解除した場合、3つの項目すべてが再レンダリングされます。 2番目のリストでは、ターゲットアイテムのみが再レンダリングされます。

class ItemsList extends React.Component { 
 
    
 
    constructor(props) { 
 
     super(props) 
 
     this.state = { 
 
      items: { 
 
       a: false, 
 
       b: false, 
 
       c: true 
 
      } 
 
     } 
 
    } 
 

 
    render() { 
 
     const self = this 
 
     return (
 
      <ul> 
 
       {Object.keys(self.state.items).map(
 
        id => (
 
         <Item 
 
          key={id} 
 
          id={id} 
 
          checked={self.state.items[id]} 
 
          handleChange={(e) => { 
 
           e.persist() 
 
           this.setState(state => ({ 
 
            ...self.state, 
 
            items: { 
 
             ...self.state.items, 
 
             [id]: e.target.checked 
 
            } 
 
           })) 
 
          }}/> 
 
        ) 
 
       )} 
 
      </ul> 
 
     ) 
 
    } 
 
} 
 

 

 
class Item extends React.Component { 
 

 
    shouldComponentUpdate(nextProps) { 
 
     return nextProps.checked != this.props.checked 
 
    } 
 

 
    render() { 
 
     console.log(`rendering ${this.props.id}`) 
 
     return (
 
      <li> 
 
       <span>{this.props.id}</span> 
 
       <input 
 
        type="checkbox" 
 
        checked={this.props.checked} 
 
        onChange={this.props.handleChange}/> 
 
      </li> 
 
     ) 
 
    } 
 
} 
 

 
class ItemsList2 extends React.Component { 
 
    
 
    constructor(props) { 
 
     super(props) 
 
     this.state = { 
 
      items: { 
 
       a: false, 
 
       b: false, 
 
       c: true 
 
      } 
 
     } 
 
    } 
 

 
    render() { 
 
     const self = this 
 
     return (
 
      <ul> 
 
       {Object.keys(self.state.items).map(
 
        id => (
 
         <Item2 
 
          key={id} 
 
          id={id} 
 
          checked={self.state.items[id]} 
 
          handleChange={(e) => { 
 
           e.persist() 
 
           this.setState(state => ({ 
 
            ...self.state, 
 
            items: { 
 
             ...self.state.items, 
 
             [id]: e.target.checked 
 
            } 
 
           })) 
 
          }}/> 
 
        ) 
 
       )} 
 
      </ul> 
 
     ) 
 
    } 
 
} 
 

 

 
class Item2 extends React.Component { 
 

 
    render() { 
 
     console.log(`rendering ${this.props.id}`) 
 
     return (
 
      <li> 
 
       <span>{this.props.id}</span> 
 
       <input 
 
        type="checkbox" 
 
        checked={this.props.checked} 
 
        onChange={this.props.handleChange}/> 
 
      </li> 
 
     ) 
 
    } 
 
} 
 

 
ReactDOM.render(<ItemsList/>, document.getElementById('app2')) 
 

 
ReactDOM.render(<ItemsList2/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.0/react.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.2.0/react-dom.js"></script> 
 
<script src="https://wzrd.in/standalone/[email protected]"></script> 
 
<div id="app"></div> 
 
<div id="app2"></div>

関連する問題