我正在尝试创建一个产品组件,它可以获得网站上提供的所有产品,并将它们显示为类似于一个盒子,当用户点击该框时,它们会被重定向到该产品页面。我正在使用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
时,不是在调用该函数时调用它,而是在渲染时调用它。有什么建议
那是因为你在每个项目的每个渲染上调用handleProductRedirect
。而不是那样,你需要在onClick
prop中发送回调,如下所示:
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
,这有助于以后捕获问题。
你的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>
);
}
}