简体   繁体   English

反应:第一次点击状态不更新

[英]React: state not updating on first click

I am working on a shopping cart sample.我正在研究购物车样本。

On each click, I am adding an object of the project to the Cart array.每次单击时,我都会将项目的一个对象添加到 Cart 数组中。 When I click the add cart button the first time, it doesn't update the Cart, but it updates on the second time.当我第一次点击添加购物车按钮时,它不会更新购物车,但会在第二次时更新。

Although, when I click the viewCart button in the render's return statement, it shows the accurate number of items in the cart.虽然,当我在渲染的返回语句中单击 viewCart 按钮时,它显示了购物车中的准确项目数。 See my code below:请参阅下面的代码:

I need to be able to see the accurate number of items in the cart without clicking the viewCart button.我需要能够在不单击 viewCart 按钮的情况下查看购物车中准确的商品数量。 The products come from a local JSON file, so I don't think there is any problem with the loading of the JSON file.产品来自本地的 JSON 文件,所以我认为加载 JSON 文件没有任何问题。

constructor (props) {
    super(props);
    this.state = {
        Cart: []
    };
    this.addItem = this.addItem.bind(this);
}

addItem(productKey) {
    this.setState({ Cart: [...this.state.Cart, ProductsJSON[productKey]]})
    console.log(this.state.Cart);
}

viewCart() {
    console.log(this.state.Cart);
}

render() {
  const AllProducts = ProductsJSON;

  var Products = AllProducts.map((item) => {
    return (
            <div className="col-4" key={item.key} >
                <a onClick={() => this.addItem(item.key)} className="btn btn-primary btn-sm">Add to Cart</a>
            </div> 
        )
})

return (
        <div className="container">
            <div className="row">
                {Products}
                <a onClick={() => this.viewCart()} className="btn btn-primary btn-sm">viewCart</a>
            </div>
        </div>
    )
}

Just because you don't see it in console.log doesn't mean it will not render correctly, the problem here is that setState is asynchronous , thus you will not see it if you console.log it right away ( console.log will execute before state is updated ), but if you still want to do log your cart, you can do:仅仅因为你没有在console.log中看到它并不意味着它不会正确呈现,这里的问题是setState异步的,因此如果你立即 console.log 就不会看到它( console.log 会在更新状态之前执行),但是如果你仍然想记录你的购物车,你可以这样做:

this.setState(
   { Cart: [...this.state.Cart, ProductsJSON[productKey]] },
   () => console.log(this.state.Cart)
)

setState accepts a function as a callback once the state has been updated.状态更新后,setState 接受一个函数作为回调。

Arber's solution makes sense but when I tried it, it produced a console warning saying: Arber 的解决方案是有道理的,但当我尝试它时,它产生了一个控制台警告说:

State updates from the useState() and useReducer() Hooks don't support the second callback argument.来自 useState() 和 useReducer() Hook 的状态更新不支持第二个回调参数。 To execute a side effect after rendering, declare it in the component body with useEffect().要在渲染后执行副作用,请使用 useEffect() 在组件主体中声明它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM