繁体   English   中英

当我运行 react.js 代码时,我有这个错误说“在渲染不同的组件时无法更新组件”

[英]I have this error that say "Cannot update a components while rendering a different component" when I run react.js code

当我运行我的代码时,出现错误“警告:在渲染不同的组件( Car )时无法更新组件( App )。要在Car中找到错误的 setState() 调用”。 如果我取出function removeFromCart(p) ,代码是好的,但如果这个 function 在 App 中,代码就坏了。

function App() {

  const [product, setProduct] = useState({
    product: data.products,
    cartItem:[],
    size: "",
    sort: ""
  })

  const removeFromCart = (p) => {
    //Copy the recent products in cart
    let cartItems = product.cartItem;
    //Take out the product you choose in cart
    setProduct({
      ...product,
      cartItem: cartItems.filter(x=>x._id!==p._id)
    });
  }

  //Add item to the product.cartItem
  const addToCart = (p) => {
    //Copy what does the cart has
    const cartItems = product.cartItem;
    let inCart = false;

    //To check the item you click is in the cart or not
    cartItems.forEach((item) => {
      if (item._id === p._id) {
        //If in the cart, the item count +1
        item.count++;
        //inCart become true to tell next statement the item you click already in in the cart,
        //WE don't need to push a need item to the cart.
        inCart = true;
      } 
    })
    //If the item you click is not in the cart, 
    //Pushing this to the cart, and set this item's count in 1. 
    if (!inCart) {
      cartItems.push({...p, count:1})
    }

    //To renew the cartItem in the product state.
    setProduct({...product, cartItem:cartItems});
  }


  //To show the items which has the size you choose
  const sizeProducts = (e) => {
    //value is the size you choose
    let { value } = e.target
    //s is the sort parameter you choose
    let s = product.sort;

    //If you didn't choose any size, show all product.
    if (value === "") {
      setProduct({ size:"", sort:s, product: data.products });
    } else {
      //If you choose any size, show the product that have the size you choose,
      //and sort it will the sort parameter yuou choose
      setProduct({
        size: value,
        sort:s,
        product: data.products.filter(p => 
          p.availableSizes.indexOf(value) >= 0
        ).sort((a, b) => 
          s === "lowest" ? ((a.price > b.price) ? 1 : -1) :
            s === "highest" ? ((a.price < b.price) ? 1 : -1) :
              ((a._id > b._id) ? 1 : -1)
        )
      });
    }
  }

  const sortProducts = (e) => {
    //The value is the sort parameter you choose
    let { value } = e.target;
    //The curr is the product after yiu choose the parameter in the size
    let curr = product.product;
    
    //Sort product
      setProduct({
        sort: value,
        product: curr.sort((a, b) => 
          value === "lowest" ? ((a.price > b.price) ? 1 : -1) :
            value === "highest" ? ((a.price < b.price) ? 1 : -1) :
              ((a._id > b._id) ? 1 : -1)
        )
      });
    }
    
  
  return (
    <div >
      <Grid xs={ 12 }>
        <Navigation />
      </Grid>
      <Grid container>
        <Grid xs={0} sm={2}></Grid>
        <Grid container xs={12} sm={8}>
          <Grid item xs={12}>
            <Filter count={product.product.length}
              size={product.size}
              sort={product.sort}
              sizeProducts={sizeProducts}
              sortProducts={ sortProducts}
            ></Filter>
          </Grid>
          <Product
            products={product.product}
            addToCart={  addToCart }
          ></Product>
        </Grid>
        <Grid xs={0} sm={2}></Grid>
      </Grid>
      
      <div className="cartSection">
        <Car cartItems={product.cartItem}
          removeFromCart={ removeFromCart } />
      </div>

    </div>
  );
}

汽车部件:

export default class Car extends Component {

    render() {
        const { cartItems } = this.props;
        return (
            <Grid container className="cart">
                <Grid container xs={12}>
                     <Grid xs={12} sm={6} md={3} >
            <div>
                {cartItems.length === 0 ?
                    (<div>Cart Empty</div>) :
                    (<div>You have {cartItems.length} in cart</div>)
                }
                
                    {cartItems.map(item => (
                        <div key={ item._id } className="cartItem">
                            <img src={item.image} alt="" />
                            <div className="info">
                                <div>
                                    { item.title }
                                </div>
                                <div>
                                    <span>{item.count} X ${item.price}</span>
                                    <Button
                                        variant="contained"
                                        color="primary"
                                        onClick={ this.props.removeFromCart(item) }
                                    >Remove</Button>
                                </div>  
                            </div>
                        </div>
                    ))}
                </div>
                   </Grid>
             </Grid>
        </Grid>
        )
    }
}

错误:

index.js:1 Warning: Cannot update a component (`App`) while rendering a different component (`Car`). To locate the bad setState() call inside `Car`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render
    at Car 
    at div
    at div
    at App 

正在做

onClick={ this.props.removeFromCart(item) } 

将立即调用this.props.removeFromCart ,导致App组件在渲染Car时更新(因为它正在更新其 state ),将其替换为:

// in the Car component
onClick={ () => this.props.removeFromCart(item) } 

请参阅下面的代码片段以了解区别,第一个代码片段甚至会在您单击按钮之前调用greet

 const App = () => { const greet = (msg) => { console.log('hello, ', msg); } return <div> <button onClick={greet('world')}>click me</button> <button onClick={() => greet('world 2')}>click me</button> </div> } ReactDOM.render(<App />, document.querySelector('#root'));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

暂无
暂无

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

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