当前位置: 首页 > 知识库问答 >
问题:

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

家西岭
2023-03-14

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

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

我有一个显示产品的表格,每个产品都有一个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类如下(这只是render函数):

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是不相关的,它正在工作,并且不会对表进行任何更改。要呈现产品,请使用以下类:

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所做的是在每个条目进入列表时覆盖它。正如您所看到的,isProduct获取一个密钥(即产品ID),但React文档说明:

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

当我使用道具时会发生这种情况,但例如,如果我使用更改产品上的描述价格数量的状态。设置state,则我得到以下警告:

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

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

共有1个答案

尹辰沛
2023-03-14

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

至于你的问题,“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
 类似资料:
  • 这听起来像是一个新手问题,但我想知道用HAL格式呈现分页资源的最佳方式是什么?现在我正在使用Spring HATEOAS API将对象转换为资源

  • 假设我的RCP项目中有一个类,并且有一个表要在其中显示如下: 这里是项目列表

  • 在GFM中,在列表中创建连续列表的正确方法是什么? 目标: 一个 我已经看了关于持续号码列表和相关问题的常见帖子,但还没有看到有人问这个问题。

  • 问题内容: 我正在与我的CompSci教授交谈,他建议将所有String 方法编写为: 而不是: 这两行都可以编译,但是我想知道第一种方法的好处是什么?我一直都是后一种方式。错了吗 什么是普通/常规? 问题答案: 第一种方法确保执行比较时不会收到 NullPointerException 。当您尝试在不存在的对象上调用方法时,抛出(发生)此异常。 以下是一些相关的切线:仔细阅读风险自负 不过要注意

  • 问题内容: 在UML图上,代表模板类的正确方法是什么? 问题答案: 在右上角带有虚线矩形的普通矩形,代表模板参数。像这样:

  • 问题内容: 我正在尝试使用一个使用大量jQuery的Layout / Template的项目。 我已经学会了将模板与ReactJS Project集成在一起,但是,我正在寻找一种可以完全替代jQuery的解决方案。 我的解决方案之一是在内部使用jQuery函数或React函数。 这种方法正确吗?这是正确的方法吗? 我在下面附上一个小例子: 这是我的职能。 问题答案: 这种方法正确吗?这是正确的方法