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],
})
}