React Render List Incorrect(列表正确,但渲染覆盖和重复)

React Render List Incorrect (List is correct, but render overwrite and duplicate)

我正在尝试做一个简单的订单系统,当用户选择数量并点击“添加到订单”时,所选菜品的信息将显示在“您的订单”区域(点击“刷新订单”查看)。我正在做的是将菜肴信息(来自 MenuEdit 组件)插入到列表(在 CustomerOrder 组件中)。

我的问题如下:我在订单中添加“Moo Goo Guy Pan”QTY:1,它会被插入到列表中,然后我添加“Teriyaki Chicken”QTY:2,它将被插入到列表中,我再次添加“Moo Goo Guy Pan”但是 QTY:3 订购,它将被插入到列表中。 uid 是用户点击“Add to Order”时的时间戳。该列表工作正常(我使用 lodash 进行深度复制),但是当渲染列表的所有项目时效果不佳。我想不出解决它的正确方法。我愿意根据您的要求提供更多信息。感谢您的宝贵时间和帮助。

我制作了一个 GIF 来演示该步骤,您可以在控制台中看到列表的变化。 link: https://github.com/Dungyichao/COVID19_Reporting_Web/blob/master/img/EggrollChenOrderSC.gif

用户点击“Add to Order”,第一步和第二步都很好。

购物车(您的订单)的渲染步骤,第一步和第二步都很好。

以下是传递给组件进行渲染的列表。请注意数量不同,这是我想要的正确列表,并且已经传递到 CartList 组件中。

我的代码和组件结构如下

Order.js

export default class CustomerOrder extends Component {

constructor(props) {

    super(props);

    this.firebase = props.firebase;
    this.sendinfo_toCart_handle = this.sendinfo_toCart_handle.bind(this);
    this.Cart_new_item_arrive = this.Cart_new_item_arrive.bind(this);
    this.remove_item = this.remove_item.bind(this);

    this.state = {
        Cart_data: [],
        Cart_new_item: '',
    }

    this.refresh_cart_handle = this.refresh_cart_handle.bind(this);
}

remove_item(e){
    console.log("Remove item uid: ", e);
}

refresh_cart_handle(){
    let {Cart_data} = this.state;
    console.log("Current Cart Data: ", Cart_data);
}

Cart_new_item_arrive(e){
    //console.log("Cart_new_item_arrive: ", e);
    this.setState({Cart_new_item: e}, () => {
        //after setstate
        this.sendinfo_toCart_handle();
    }); 
    
    
}

sendinfo_toCart_handle(){
    let {Cart_new_item, Cart_data} = this.state;
    let deepcopy_list = _.cloneDeep(Cart_data);
    deepcopy_list.push(Cart_new_item);
    this.setState({Cart_data: deepcopy_list});
}


render() {

    let {Cart_data} = this.state;

    return (
        <div style={order_style}>

            <div style={{
                
            }}>
                <h3>Menu</h3>
                <MenuEdit firebase={this.firebase} CartAdd={this.Cart_new_item_arrive} />

            </div>

            <div style={{
                
            }}>
                <h3>Your Order</h3>
                <Cart data_array={Cart_data} remove_item={this.remove_item} />   {/*remove_item={this.remove_item}*/}
                <Button onClick={this.refresh_cart_handle}>Refresh Order</Button>
            </div>

        </div>
    );

}

}

Cart.js

export default class Cart extends Component {

constructor(props) {

    super(props);

}

render() {
    return (
        <div>
            <div>
                <Scroll>
                    
                        <CartList data_array={this.props.data_array} remove_item={this.props.remove_item} />  {/*remove_item={this.props.remove_item}*/}
                    
                </Scroll>
            </div>
            <div>
                <div><Button>Refresh</Button></div>
                <div>
                    <Button>Cancel</Button> {'  '}
                    <Button>Place Order</Button>
                </div>
                
            </div>


        </div>
    );
}

}

CartList.js

export default class CartList extends Component {

constructor(props) {

    super(props);

}

render(){

    let display_data = this.props.data_array;
    let null_page = [];
    console.log("Data in CartList.js: ", display_data)

    if(display_data[0]){
        return(       
            display_data.map(
                (cart_item, idx) => {
                    //console.log("In Map", idx, ' Item: ', cart_item);
                    return(
                        <div>
                            <CartItem key={idx} u_key={idx + 1} 
                            Cart_item_info={cart_item} 
                            remove_item={this.props.remove_item} /> {/*remove_item={this.props.remove_item}*/}
                        </div>
                    );
                }
            )
        )
    }
    else{
        return(
            <div>
                <p>Add Your Favorite Dishes to Here</p>
            </div>
        );
    }

}

}

CartItem.js(呈现列表中的每个项目)

export default class CartItem extends Component {

constructor(props) {

    super(props);
    this.state = {
        show_toggle: true,
        cart_item_info: this.props.Cart_item_info,
        u_key: this.props.u_key,
        
    }
    //cart_item_info: this.props.Cart_item_info,
    this.remove_item_handle = this.remove_item_handle.bind(this);
}

remove_item_handle(){
    let {cart_item_info} = this.state;
    this.props.remove_item(cart_item_info.uid);
}

render() {
    let {cart_item_info, u_key} = this.state;
    //console.log("Return CartItem")
    return (
        <div key={u_key} >
            <Accordion>
                <Card>
                    <Accordion.Toggle as={Card.Header} eventKey="0">
                        <div style={item_style}>                                                          
                            <div style={{flex: '1'}}>{u_key}.</div>
                            <div style={{flex: '7'}}> {cart_item_info.dish_name}</div>
                            <div style={{flex: '2'}}>X {cart_item_info.qty}</div>
                            <div style={{flex: '2'}}>${cart_item_info.Tprice}</div>                                                       
                        </div>
                       
                    </Accordion.Toggle>
                    <Accordion.Collapse eventKey="0">
                        <Card.Body>
                            <Button onClick={this.remove_item_handle} >Remove</Button>
                        </Card.Body>
                    </Accordion.Collapse>
                </Card>                  
            </Accordion>
        </div>
    );
}

}

更新您的 cartItem.js 文件。它应该是功能组件。

const CartItems = (props) => {

console.log(props.Cart_item_info);

return (
<div key={props.u_key} >
<Accordion>
<Card>
<Accordion.Toggle as={Card.Header} eventKey="0">
<div>
<div style={{ flex: '1' }}>{props.u_key}.</div>
<div style={{ flex: '7' }}> {props.Cart_item_info.dish_name}</div>
<div style={{ flex: '2' }}>X {props.Cart_item_info.qty}</div>
<div style={{ flex: '2' }}>${props.Cart_item_info.Tprice}</div>
</div>

</Accordion.Toggle>
<Accordion.Collapse eventKey="0">
<Card.Body>
<div>No</div>
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>
</div>
);
}

我终于找到了问题的根本原因,但我没有在问题中透露它,因为我什至认为这不会导致问题

问题出在 MenuItem 组件(用户可以单击添加到订单的菜单项)。正确的方法是清除所有数据(将要插入 Order.js 中的列表)在 MenuItem 组件已经插入的状态下保留。通过这样做,您可以防止再次发送任何原始数据。

同样在与 Deepak 的聊天室中,他提出了以下一些提示:

  1. 当你只想展示一些东西而不需要状态管理时,你更喜欢功能组件。
  2. 键有助于识别列表中的项目更改。