Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用上下文API从子级到父级,onClick被多次调用-ReactJs_Javascript_Reactjs_Jsx - Fatal编程技术网

Javascript 使用上下文API从子级到父级,onClick被多次调用-ReactJs

Javascript 使用上下文API从子级到父级,onClick被多次调用-ReactJs,javascript,reactjs,jsx,Javascript,Reactjs,Jsx,父组件: import React, { Component } from 'react'; import axios from "axios"; import './App.css'; import Header from './components/Header/Header'; import List from './components/List/list'; import Context from './Context/productsContext'; class App exte

父组件:

import React, { Component } from 'react';
import axios from "axios";
import './App.css';
import Header from './components/Header/Header';
import List from './components/List/list';
import Context from './Context/productsContext';

class App extends Component {
  state = {
    products : [],
    cartProducts:[]
  }
  componentDidMount () {
    console.log("effect");
    fetch("http://localhost:3001/ITEMS").then(resp => resp.json())
    .then(result => this.setState({
      products: result
    }));
  }

  addToCart = (product) => {
    const prod = this.state.products;
    prod.push(product);
    this.setState({
      cartProducts:prod
    })
  }

  render () {
    console.log("PRoducts",this.state)
    return (
      <Context.Provider value={{
        products: this.state.products,
        cartProducts:this.state.cartProducts,
        addToCart: (prod) => this.addToCart(prod)
      }}>
      <div className="App">
      <Header />
      <List />
      </div>
      </Context.Provider>
    );
  }

}

export default App;
import React,{Component}来自'React';
从“axios”导入axios;
导入“/App.css”;
从“./components/Header/Header”导入标题;
从“./components/List/List”导入列表;
从“/Context/productsContext”导入上下文;
类应用程序扩展组件{
状态={
产品:[],
产品:[]
}
组件安装(){
控制台日志(“效果”);
取回(“http://localhost:3001/ITEMS)然后(resp=>resp.json()
.然后(结果=>this.setState({
产品:结果
}));
}
addToCart=(产品)=>{
const prod=this.state.products;
产品推送;
这是我的国家({
产品:产品
})
}
渲染(){
console.log(“PRoducts”,this.state)
返回(
此。添加到零件(prod)
}}>
);
}
}
导出默认应用程序;
子组件:

import React from 'react';
import Context from '../../Context/productsContext';
import './list.scss';

function List(props) {
  return (
    <div className="main-container">
     <div className="filter-container">
          Hello
     </div>
     <div className="list-container">
     <Context.Consumer>
       {
         value => {
           return value.products.map((v,i) => 
           <div key={i} className="card">
             <img src={v.image} alt={v.name} style={{width:"25%"}} />
             <div className="container">
               <h4>{v.name}</h4>
               <button className="add-button" onClick={() => value.addToCart(v)}>Add To Cart</button>
             </div>       
           </div>

           )
         }

       }
     </Context.Consumer>
     </div>

    </div>
  );
}

export default List;
从“React”导入React;
从“../../Context/productsContext”导入上下文;
导入“/list.scss”;
功能列表(道具){
返回(
你好
{
值=>{
返回值.products.map((v,i)=>
{v.name}
value.addToCart(v)}>添加到购物车
)
}
}
);
}
导出默认列表;
当我使用上下文API从child调用函数addToCart时,它调用的次数与数组长度相同,是否有方法只调用一次并与父级通信? 这是我单击按钮时得到的值,它将添加所有值,但我只想在单击按钮时向数组添加一个特定值。


您知道回调被多次调用吗?或者只是处理程序逻辑多次添加值
v
?根据您在
addToCart
处理程序中使用的array::push(与不改变状态对象的方法相比),您可能还存在其他逻辑错误

我猜您可能不是有意保存对
this.state.products
的引用,使用array::push对其进行变异,然后将引用保存回
this.state.cartProducts
下的状态

addToCart = (product) => {
  const prod = this.state.products; // <-- saved state reference
  prod.push(product); // <-- mutate state reference!!
  this.setState({
    cartProducts:prod // <-- saved reference to other state, both now equal
  })
}

试试这个,看看问题是否解决。

谢谢,这就是我的意思,我错过了那部分
addToCart = (product) => {
  const { cartProducts } = this.state;
  this.setState({
    cartProducts: [...cartProducts, product],
  })
}