React需要渲染两次才能更新我的值

时间:2018-04-26 21:20:44

标签: javascript reactjs render jsx

这是我的前提:

我有一个cartItems状态,这是它的基本结构。

空时:

cartItems: []

填充时:

cartItems: [{
    id: 999,
    date: "Wed Jan 24 2018 19:30:00 GMT-0500 (EST)",
    tickets: [{
        amount: 49.99,
        quantity: 2
    }]
},{
    id: 998,
    date: "Wed Jan 24 2018 19:30:00 GMT-0500 (EST)",
    tickets: [{
        amount: 49.99,
        quantity: 1
    }]
}]

我的应用程序中还有一个显示票数总计的购物车。

所以为了显示这些总数,我在JSX中使用了这样的东西:

<span className="my-total">
{                             
    this.props.cartItems.reduce((grandTotal, item) => {
        return grandTotal + item.tickets.reduce((runningTotal, ticket) => {
            return runningTotal + ticket.quantity || 0
        }, 0);
     }, 0)
}
</span>

所以基本上我循环遍历this.props.cartItems以计算总票数并提供减少0的起点。

但是,当我第一次向购物车添加门票时,我的总数不会更新。如果我控制台记录返回的值我得到0.虽然我的cartItems状态正确更新,我可以看到新添加的票证。

触发updateCart方法后,我要么更新ticket数组中的数量,要么将新对象推送到cartItems,然后更新cartItems的状态。

但是,第二次使用完全相同的updateCart方法添加票证时,现在可以正确更新总数。如果我控制台记录返回的值,我会得到正确数量的票。

我希望当我的cartItems状态第一次更新时,React会重新渲染,而我的reduce会启动并更新显示的值。

2 个答案:

答案 0 :(得分:1)

缺少一些可以检测到实际问题的部分。尽管如此,这是一个假设一些事情的解决方案:

  1. 您的州包含cartItemsgrandTotal
  2. 实际数据来自this.props
  3. 您在willReceiveProps
  4. 中更新了状态

    state = {
        cartItems: [],
        grandTotal: 0
    }
    
    componentWillReceiveProps(nextProps) {
        const grandTotal = nextProps.cartItems.reduce((grandTotal, item) => {
            return grandTotal + item.tickets.reduce((runningTotal, ticket) => {
                const total = ticket.amount * ticket.quantity;
    
                return Number.isNaN(total) ? runningTotal : runningTotal + total;
            });
        });
    
        this.setState({
            cartItems: nextProps.cartItems,
            grandTotal
        })
    }
    
    render() {
        return (
            <div>
                <ul>
                    {
                        this.state.cartItems.map((data) => <Draw key={data.id} data />)
                    }
                </ul>
                <p>{this.state.grandTotal}</p>
            </div>
        )
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

    希望这有帮助!

答案 1 :(得分:0)

(代表作者提问)

这已经解决了。错误在reduce函数中:

    this.props.cartItems.reduce((grandTotal, item) => {
        return grandTotal + item.tickets.reduce((runningTotal, ticket) => {
            return runningTotal + ticket.quantity || 0
        }, 0);
     }, 0)

在这一行:

return runningTotal + ticket.quantity || 0

我认为这会评估ticket.quantity,如果它是未定义的,则将其更改为0,但是它没有这样做。相反,当ticket.quantity未定义时,它会将整个表达式更改为= 0.