Javascript 使用ReactJS中的键显示列表中的项目的正确方法是什么?

Javascript 使用ReactJS中的键显示列表中的项目的正确方法是什么?,javascript,html,reactjs,Javascript,Html,Reactjs,我试图做的是创建一个产品列表,并在产品进入时持续显示它。为此,我使用键(区分产品)。从中我们知道: “键”是创建元素列表时需要包含的特殊字符串属性 我有一个显示产品的表格,每个产品都有一个ID、一个描述、一个价格和一个数量(列表上此类产品的数量)。每次将新产品添加到列表中时,它必须在最后一个显示的产品之后显示该产品,但是,如果该产品已在列表中,它必须更改对象数据以显示新值。例如: ------------------------------------ | Description | Pric

我试图做的是创建一个产品列表,并在产品进入时持续显示它。为此,我使用键(区分产品)。从中我们知道:

“键”是创建元素列表时需要包含的特殊字符串属性

我有一个显示产品的表格,每个产品都有一个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,我的Table类是这样的(这只是渲染函数)

返回(
描述
价格
量
{}
帕加尔
);
对于这个,Total是不相关的,它正在工作,并且不会对表进行任何更改。要呈现产品,请使用以下类:

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>
        )
    }
});
var Product=React.createClass({
道具类型:{
数量:React.PropTypes.number.isRequired,
描述:React.PropTypes.string.isRequired,
producttotal:React.PropTypes.number.isRequired
},
getInitialState:函数(){
返回{
数量:this.props.quantity,
description:this.props.description,
producttotal:this.props.producttotal
};
},
渲染:函数(){
返回(
{this.props.quantity}
{this.props.description}
{this.props.producttotal}
)
}
});
现在React所做的是在每个条目进入列表时覆盖它。正如您所看到的,is
Product
获取一个密钥(即产品ID),但是

键有助于识别哪些项已更改、已添加或已删除。应为数组中的元素提供键,以使元素具有稳定的标识

当我使用
道具
时会发生这种情况,但例如,如果我使用
This.setState
更改
产品
上的
说明
价格
数量
的状态,则我会收到以下警告:

警告:FlattChildren(…):遇到两个具有相同密钥的子项。子密钥必须是唯一的;当两个子项共享密钥时,将只使用第一个子项


那么,使用ReactJS中的键显示列表中的项的正确方法是什么?我在React文档和论坛中找不到太多帮助。顺便说一句,谢谢。

我在ES6中写过这篇文章,但希望这会有所帮助。我不知道Total组件应该是什么样子,但计算了有意义的
Total
prop,并显示了它,因此它应该很容易替换

至于你的问题,“key”属性应该始终是持久对象的一致标识符;可以将其视为缓存渲染的哈希值。例如,我使用了价格和名称,因为它们在应用程序中应该是一致的

通常,会列出列表。如果您有一个很长的列表,那么最好计算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
import React,{Component}来自“React”
从“./产品”导入产品
//要使用的基本模拟数据
var项目=[‘牛奶’、‘咖啡’、‘牛奶’、‘咖啡’、‘年糕’、‘咖啡’];
康斯特产品=
[
{说明:'牛奶',价格:2.49},
{说明:'咖啡',价格:1.25},
{说明:'年糕',价格:1.49}
];
类表扩展组件
{
渲染()
{
让productList=Products.map((产品)=>
{
让数量=项目.过滤器((项目)=>(项目==产品.说明)).length,
列表项=
{
key:(product.description+product.price),//任何一致的散列都可以在这里执行
description:product.description,
量
价格:(产品价格*数量)
};
返回列表项;
});
让total=productList.map((p)=>p.price)。reduce((a,b)=>(a+b),0);
返回(
描述
价格
量
{productList.map((p)=>())}
{total}
帕加尔
);
}
}
导出默认表

很抱歉,我编辑了我的问题,解释了Total元素在这里不相关。顺便说一下,您的代码段显示了一个错误:
{“message”:“SyntaxError:导入声明可能只出现在模块的顶层”,“filen”
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