2016-11-16 12 views
2

私がしようとしているのは、製品リストを作成し、製品が入ったときにそれを継続的に表示することです。このため私はキーを使っています(製品を区別するために)。 React documentationから、我々はことを知っている:ReactJSのキーを使ってリストから項目を表示する正しい方法はありますか?

A "key" is a special string attribute you need to include when creating lists of elements.

私は製品を表示するテーブルを持って、それぞれの製品には、説明、価格と数量(リスト上の製品のようなものの量)IDを持っています。新しい製品がリストに追加されるたびに、最後に表示された後に製品を表示する必要がありますが、製品が既にリストにある場合は、新しい値を表示するようにオブジェクトデータを変更する必要があります。例:例えば、コーヒーは、それは次のように表示されます追加され、

ので
------------------------------------ 
| Description | Price | Quantity | 
------------------------------------ 
| Milk  | $2.49 |  1 | 
------------------------------------ 

、:

------------------------------------ 
| Description | Price | Quantity | 
------------------------------------ 
| Milk  | $2.49 |  1 | 
------------------------------------ 
| Coffee  | $1.25 |  1 | 
------------------------------------ 

しかし、別の牛乳が追加された場合、値は次のようになります。

------------------------------------ 
| Description | Price | Quantity | 
------------------------------------ 
| Milk  | $4.98 |  2 | 
------------------------------------ 
| Coffee  | $1.25 |  1 | 
------------------------------------ 

これまでのところ、ES5を使用して私はこのようなテーブルクラスを持っています(これはレンダリング関数です):

return (
      <div className="data"> 
       <div className="col-md-6"> 
        <table id="table" className="table"> 
         <thead> 
          <th>Description</th> 
          <th>Price</th> 
          <th>Quantity</th> 
         </thead> 
         <tbody> 
          {<Product key={key} description={description} price={price} quantity={quantity} />} 
         </tbody> 
        </table> 
       </div> 
       <div className="col-md-6 col-centered"> 
        <div className="row"><Total key={total} total={total} /></div> 
        <div className="row"> 
         <button href="#" className="btn btn-default btn-lg">Pagar</button> 
        </div> 
       </div> 
      </div> 
     ); 

合計は、関連性がなく、動作しており、テーブルに変更はありません。製品をレンダリングするには、ここにクラスです。今のところ、それはリストに入ったときに、各項目を上書きしているんリアクト何

var Product = React.createClass({ 

    propTypes: { 
     quantity: React.PropTypes.number.isRequired, 
     description: React.PropTypes.string.isRequired, 
     producttotal: React.PropTypes.number.isRequired 
    }, 

    getInitialState: function() { 
     return{ 
      quantity: this.props.quantity, 
      description: this.props.description, 
      producttotal: this.props.producttotal 
     }; 
    }, 

    render: function() { 
     return (
      <tr> 
       <td>{this.props.quantity}</td> 
       <td>{this.props.description}</td> 
       <td>{this.props.producttotal}</td> 
      </tr> 
     ) 
    } 
}); 

。あなたが見ることができるようにProduct(つまり、製品IDです)キーを取得しますが、React documentationは言うです:

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity.

私はpropsを使用する場合に発生しますが、例えば、私はdescriptionpricequantityの状態を変更した場合だから、

Warning: flattenChildren(...): Encountered two children with the same key. Child keys must be unique; when two children share a key, only the first child will be used.

、ReactJSのキーを使用して、リストから項目を表示するための正しい方法は次のとおりです。this.setStateProductに、私はこの警告を取得しますか?私はReactのドキュメントやフォーラムで多くの助けを得ることができませんでした。途中でありがとう。

答えて

0

私はこれをES6で書いたことがありますが、うまくいけばこれが役に立ちます。 Totalコンポーネントの外観はわかりませんでしたが、意味のあるtotal小数点を計算して表示しましたので、簡単に置き換えることができます。

"キー"小道具は、常に維持されるオブジェクトの一貫した識別子でなければなりません。これをキャッシュ・レンダリングのハッシュ値と考えてください。たとえば、価格と名前はアプリ内で一貫している必要があるため、使用しました。

通常、リストはマップされます。本当に長いリストを持っているなら、それを高速化するためにcomponentWillReceivePropsの値を計算することは良い考えですが、最終的にデータストアが最終的にそれを処理する最終的にFLUXのようなものを使用するべきです。いずれの場合においても

あなたが提供された例での作業の説明文字列のリストなどの項目のリストを与えられたとき、これはかなり原油と不完全な例が、製品アウトテーブルのマッピングであるここにある:

import React, {Component} from 'react' 
import Product from './Product' 

// basic mock data to work with 
var items = ['Milk', 'Coffee', 'Milk', 'Coffee', 'Rice-cakes', 'Coffee']; 

const Products = 
[ 
    { description : 'Milk',  price : 2.49 }, 
    { description : 'Coffee',  price : 1.25 }, 
    { description : 'Rice-cakes', price : 1.49 } 
]; 

class Table extends Component 
{ 
    render() 
    { 
     let productList = Products.map((product)=> 
     { 
      let quantity = items.filter((item)=>(item == product.description)).length, 
       listItem = 
       { 
        key   : (product.description + product.price), //any consistent hash will do here 
        description : product.description, 
        quantity, 
        price : (product.price * quantity) 
       }; 

      return listItem; 
     }); 

     let total = productList.map((p)=>p.price).reduce((a, b)=>(a+b),0); 

     return (
      <div className="data"> 
       <div className="col-md-6"> 
        <table id="table" className="table"> 
         <thead> 
         <th>Description</th> 
         <th>Price</th> 
         <th>Quantity</th> 
         </thead> 
         <tbody> 
         {productList.map((p)=>(<Product {...p} />))} 
         </tbody> 
        </table> 
       </div> 
       <div className="col-md-6 col-centered"> 
        <div className="row">{total}</div> 
        <div className="row"> 
         <button href="#" className="btn btn-default btn-lg">Pagar</button> 
        </div> 
       </div> 
      </div> 
     ); 
    } 
} 

export default Table 
+0

申し訳ありませんが、Total要素がここでは関連していないことを説明する質問を編集しました。ところで、あなたのスニペットにエラーが表示されます: '{ " message ":" SyntaxError:インポート宣言はモジュールのトップレベルにしか表示されません "、 " filename ":" http://stacksnippets.net/js "、 "lineno":13、 "colno":8 } –

+0

ああ、残念です。私はそれが実行可能であることを意味しませんでした。まだStackExchangeに精通していません。私はそれをどのように取り出すかを考え出すでしょう。 – rob2d

+0

(BabelのようなES6をサポートするコンパイラやGoogle Chromeでうまく動作するはずです) – rob2d

関連する問題