这是在ReactJS中使用键显示列表项的正确方法
Whichis the correct way to display items from a list using keys in ReactJS?
我要做的是创建一个产品列表,并在产品进入时连续显示它。为此,我使用键(来区分产品)。从React文档中我们知道:
"key"是一个特殊的字符串属性,在创建元素列表时需要包含。
我有一个显示产品的表,每个产品都有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>
);
Total,对于这个,是不相关的,它是工作的,它不会对表做任何改变。要渲染Product,下面是类:
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>
)
}
});
现在React所做的是覆盖每个项目时,它进入列表。正如您所看到的,Product
获得一个键(即产品ID),但是React文档说:
键帮助React识别哪些项被更改、添加或删除了。为了给数组中的元素提供一个稳定的标识,应该给数组中的元素赋键。
当我使用props
时发生这种情况,但例如,如果我用this.setState
改变Product
上的description
, price
和quantity
的状态,那么我得到这个警告:
警告:扁平化儿童(…):遇到两个具有相同键的孩子。子键必须是唯一的;当两个子节点共享一个密钥时,只有第一个子节点会被使用。
那么,在ReactJS中使用键从列表中显示项目的正确方法是什么?我在React文档和论坛中找不到太多帮助。顺便谢谢。
我是在ES6中写的,但希望这能有所帮助。我不知道Total组件应该是什么样子,但是计算了有意义的total
道具并显示了它,所以它应该很容易替换。
至于你的问题,"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
- 在Javascript中,当使用array.prush方法向列表中添加项目时,如何对其进行排序
- 什么'是从对象列表中一次编辑一个对象的正确Angular/Firebase方法
- 在带有参数列表的表单submit上调用一个方法
- 从填充了 AJAX 的下拉列表中获取控制器的操作方法中的值
- 如何将对象列表传递到MVC4中的控制器方法
- 什么'这是ES6中制作重复元素列表的等效方法
- javascript:更改应用到的数组的数组方法列表
- 未捕获的类型错误:对象#<节点列表>没有方法'addEventListener'
- jQuery验证插件-比较两个选择下拉列表的自定义方法
- 来自Jquery的“.on”方法在动态生成的下拉列表后不起作用
- 有没有一种方法可以在使用html脚本的同时将列表实现为按钮函数
- 有没有一种方法可以在没有jQuery的情况下获得JavaScript中当前添加到后台的事件列表
- 调用.ajax方法得到未定义的json结果,返回json格式列表<字符串>
- 如何将带有数组列表的$(“form”).serialize()从AJAX方法传递到mvc控制器
- 如何使用ajax调用获取数组列表数据(将数组列表数据控制器传递给ajax方法)
- 级联下拉列表mvc3,create方法
- 在调用方法来填充详细信息网格之前,如何从填充的下拉列表中获取信息
- 调用 HTTP get 方法以使用 angular JS 在下拉列表中填充结果
- 如何将 hasNext() 和 hasPrevious() 方法用于 Node 的“智能列表”链表模块
- IE 列表方法的替代方法