我正在尝试创建一个产品组件,该组件可以获取网站上提供的所有产品,并且有点像盒子一样显示每个产品,当用户点击该框时,他们会被重定向到产品页面。我使用的是react和redux,而且我对onClick有困难。这就是我的代码看起来的样子
class Products extends Component{
constructor(){
super();
this.state = {
products: [...Some array]
};
}
handleProductRedirect(productNumber){
console.log(productNumber)
// Redux function
// this.props.handleRedirect(productNumber)
}
render(){
var products = this.state.products
return (
<div id="content">
{product &&
<div id="searchContent">
{product.map(element => <Item element={element}
handleProductRedirect={this.handleProductRedirect.bind(this)}
key={element['productNumber']}/>)}
</div>
}
</div>
</div>
)
}
};
class Item extends Component{
render(){
var element = this.props.element;
return (
<div id="itemBox" onClick={this.props.handleProductRedirect(element['productNumber'])}>
<h3>{elementTitle.slice(0, 85)}</h3>
<p>{element.Manufacturer}</p>
</div>
)
}
}
因此组件从api获取产品,一旦获得它们,它就会迭代它们。但是,我注意到使用chromes开发人员控制台,即使该项目没有被点击,它也会遍历它调用<Item />
的每个handleProductRedirect
组件。它自动完成。点击div itemBox
时,不是在调用该函数时调用它,而是在渲染时调用它。任何建议
答案 0 :(得分:1)
那是因为你在每个项目的每个渲染上调用handleProductRedirect
。而不是那样,你需要在onClick
道具中发送回调,如下所示:
class Item extends Component{
onClickItem = () => { // <=== Defines the callback and bind it to the instance
const { element } = this.props;
this.props.handleProductRedirect(element['productNumber']);
};
render(){
var element = this.props.element;
return (
<div id="itemBox" onClick={this.onClickItem}>
<h3>{elementTitle.slice(0, 85)}</h3>
<p>{element.Manufacturer}</p>
</div>
)
}
}
这样你就不会在每个渲染上调用回调,而是在用户实际点击元素时。
此外,不要忘记在您的组件上定义propTypes
,这有助于以后发现问题。
答案 1 :(得分:0)
你的onClick在这里调用函数:
onClick={this.props.handleProductRedirect(element['productNumber'])}>
相反,你应该返回一个用参数调用它的函数。你可以通过制作这样的箭头函数来做到这一点:
onClick={() => this.props.handleProductRedirect(element['productNumber'])}>
但最好的方法是将其提取到一个类方法中(这样你就不会得到不必要的重新渲染):
class Item extends Component {
clickProduct = () => {
this.props.handleProductRedirect(this.props.element['productNumber']);
}
render() {
var element = this.props.element;
return (
<div id="itemBox" onClick={this.clickProduct}>
<h3>{elementTitle.slice(0, 85)}</h3>
<p>{element.Manufacturer}</p>
</div>
);
}
}