2016-07-10 7 views
1

これは私が達成しようとしているものです。私はProductListの成分の中に示されている2つの反応成分ProductProductInfoPanelを持っています。 Productには、製品名や価格などの製品に関する選択情報が表示されます。製品をクリックすると、詳細がProductInfoPanelに表示されます。だから私はProductInfoPanelにクリックしたワウの羽を渡す必要があります。React:状態を使わずにレンダリングメソッドの外からコンポーネントの小道具を更新する

ここでは、どのようにそれらを一緒に接続しています。各Productは、クリックハンドラを受け取り、呼び出されたときにproductオブジェクトを戻し、それはProductInfoPanelの小道具に渡されます。 ProductListは、何がクリックされたかを追跡するために状態を使用するため、変更すると情報パネルの再レンダリングがトリガーされます。

class ProductList extends React.Component { 
    render() { 
    return (
     <div> 

     <div className='content'> 

      <ul> 
      { this.props.products.map((product, index) => { 
       return (
       <li key={index}> 
        <Product product={product} 
        clickHandler={this.onProductClicked.bind(this)}/> 
       </li> 
      ); 
      })} 
      </ul> 

     </div> 

     <div className='side-panel'> 
      <ProductInfoPanel product={this.state.selectedProduct} /> 
     </div> 

     </div> 
    ); 
    } 

    onProductClicked(clickedProduct) { 
     // Use the product object that was clicked, and updates the state. 
     // This updates the info panel content. 
     this.setState({ selectedProduct: clickedProduct }); 
    } 

} 

ここでは、2つのコンポーネントがどのように構築されるかについて説明します。

class Product extends React.Component { 
    render() { 
    // Even though it needs only name and price, it gets the whole product 
    // object passed in so that it can pass it to the info panel in the 
    // click handler. 
    return (
     <div onClick={this.onClicked.bind(this)}> 
     <span>{this.props.product.name}</span> 
     <span>{this.props.product.price}</span> 
     </div> 
    ); 
    } 

    onClicked(e) { 
    this.props.clickHandler(this.props.product); 
    } 
} 

class ProductInfoPanel extends React.Component { 
    render() { 
    // Info panel displays more information about a product. 
    return (
     <ul> 
     <li>{this.props.product.name}</li> 
     <li>{this.props.product.price}</li> 
     <li>{this.props.product.description}</li> 
     <li>{this.props.product.rating}</li> 
     <li>{this.props.product.review}</li> 
     </ul> 
    ); 
    } 
} 

これは私が思いつくことができる最高ですが、どの製品がクリックされたのかを把握するために状態を使用しても間違っています。つまり、実際にコンポーネントの状態ではありませんか?

私は、参照のpropsを更新することができる場合は、私は各ProductからProductInfoPanelへの参照を渡すためにしようと思い、render方法の外からコンポーネントを反応するので、彼らは彼らのクリックハンドラでそれを更新し行うことができます。

私が望むものを達成し、クリックしたものを追跡するために状態を使用しないようにする方法はありますか?

答えて

3

reduxのようなフラックスのようなライブラリ、またはmobxのような代替品を使用してコンポーネントから状態管理を削除することはできますが、私の個人的な気持ちは、大きな利点があると本当に感じるまでプロジェクトに別の抽象化レイヤーを追加することになります。

私は、デフォルトでreduxを使用してプロジェクトを開始しましたが、実際にはかなり小さくて単純なプロジェクトでは、redux実装を導入することの複雑さが過度であることが判明したので、標準状態の使用を恥ずかしく思って、それを管理する別の図書館を紹介しなければならないときは、わかりませんが、まずは最も簡単で簡単な方法を最初に実行するのが最も安全だと分かりました。あなたは本当に別の依存関係をもたらして実際の利益があると感じています。あなたの現在のコード上のアドバイスの


数ビット...

あなたがそうのような性質であなたの機能を結合している:あなたが機能bindを呼び出すとき

<Product product={product} clickHandler={this.onProductClicked.bind(this)}/> 

はそれが実際に返しますしたがって、Reactの調整者は、それをコンポーネントに入ってくる新しい小道具として見て、常にサブコンポーネントツリーを再描画します。知っておくべきこと。 - それはだ場合、あなたのproductモデル(から一意の識別子を使用して検討すべきであるあなたは上記の彼らのユニークなkey小道具としてindexを提供しているさらに

class ProductList extends React.Component { 
    constructor(props) { 
    super(props); 
    this.onProductClicked = this.onProductClicked.bind(this); 
    } 
    render() { 
    ... 
     <li key={index}> 
      <Product product={product} 
      clickHandler={this.onProductClicked}/> 
     </li> 
    ... 
    } 
} 

、:別のアプローチとして、あなたはそうのようなあなたのコンストラクタで、事前バインディングを行うことができます利用可能)。リストから項目を追加または削除すると、Reactは、Productコンポーネントインスタンスのすべてを再レンダリングする必要があるかどうかを知るために、より多くの情報を得ることができます。例えば

render() { 
    ... 
    { 
     this.props.products.map((product) => 
     <li key={product.id}> 
      <Product product={product} 
      clickHandler={this.onProductClicked}/> 
     </li> 
    ) 
    } 

    ... 
} 

はここにこれらの概念について詳しく読む: https://facebook.github.io/react/docs/advanced-performance.html

1

私はそれは罰金だと思います。 SelectedProductの変更に応答したコンポーネントがさらにある場合、親コンポーネントの状態を制御する値がより明白になります。あなたの場合、単一のコンポーネントだけが変更されるため、必要ではないように見えるかもしれません。

あなたProductSelectedProductを強調することで応答し、そしてRecentlyViewedProductsリストはSelectedProductに何らかの方法で応答した場合しかし、それはSelectedProductProductInfoPanelの状態が、より高い状態ではないことが明らかになるだろうオブザーバーであるアプリケーションのレベルの部分です。

関連する問題