React onClick 在加载时多次触发,并且组件道具中不包含回调函数
React onClick fires multiple times on load and doesn't contain callback function in component props
我相信我有两个基本问题,它们可能是相关联的。我试图在嵌套组件上放置一个带有回调函数的事件处理程序。它似乎没有做任何事情,所以我用 JSON.stringify(this.props)
的警报替换了回调函数,看看这是否会有所帮助。它说明了两个问题:1)我的回调函数不在道具中。 2) 警报在页面加载时弹出 2 次,但没有像预期的那样在点击时弹出。我正在处理 this React tutorial。以下是相关组件:
var App = React.createClass({
mixins: [Catalyst.LinkedStateMixin],
getInitialState: function(){
return {
fishes: {},
order: {}
}
},
componentDidMount: function(){
base.syncState(this.props.params.storeId + '/fishes', {
context: this,
state: 'fishes'
});
var localStorageRef = localStorage.getItem('order-' + this.props.params.storeId);
if(localStorageRef){
this.setState({
order: JSON.parse(localStorageRef)
});
}
},
componentWillUpdate: function(nextProps, nextState){
localStorage.setItem('order-' + this.props.params.storeId, JSON.stringify(nextState.order));
},
loadSamples: function(){
this.setState({
fishes: require('./sample-fishes.js')
});
},
addFish: function(fish){
var timestamp = (new Date()).getTime();
this.state.fishes['fish-' + timestamp] = fish;
this.setState({ fishes: this.state.fishes });
},
removeFish: function(key){
if(confirm("Are you sure you want to remove this fish?")){
this.state.fishes[key] = null;
this.setState({ fishes: this.state.fishes });
}
},
addToOrder: function(key){
this.state.order[key] = this.state.order[key] + 1 || 1;
this.setState({ order: this.state.order });
},
// <<<<<<<< the function I'm having trouble with >>>>>>>>
removeFromOrder: function(key){
alert('hi');
delete this.state.order[key];
this.setState({ order: this.state.order });
},
renderFish(key){
return <Fish key={key} index={key} details={this.state.fishes[key]} addToOrder={this.addToOrder}/>
},
render: function(){
return (
<div className="catch-of-the-day">
<div className="menu">
<Header tagline="Fresh Seafood Market"/>
<ul className="list-of-fish">
{/*{ Object.keys(this.state.fishes).map(this.renderFish) }*/}
{ Object.keys(this.state.fishes).length > 0 ? Object.keys(this.state.fishes).map(this.renderFish) : <li>No Fishes!</li> }
</ul>
</div>
// <<<<<<<< I pass the function through to the Order component >>>>>>>>
<Order fishes={this.state.fishes} order={this.state.order} removeFromOrder={this.removeFromOrder}/>
<Inventory fishes={this.state.fishes} addFish={this.addFish} removeFish={this.removeFish} loadSamples={this.loadSamples} linkState={this.linkState}/>
</div>
)
}
});
var Order = React.createClass({
renderOrder: function(key){
var fish = this.props.fishes[key];
var count = this.props.order[key];
// <<<<<<<< the onClick I'm having trouble with >>>>>>>>
var removeButton = <button onCLick={this.props.removeFromOrder.bind(null, key)}>×</button>
// var removeButton = <button onCLick={alert(JSON.stringify(this.props))}>×</button>
if(!fish) {
return <li key={key}>Sorry, that fish is no longer available! {removeButton}</li>
// return <li key={key}>Sorry, that fish is no longer available!</li>
}
return (
<li key={key}>
{count}lbs
{" " + fish.name}
<span className="price">{helpers.formatPrice(count * fish.price)} {removeButton}</span>
{/*<span className="price">{helpers.formatPrice(count * fish.price)}</span>*/}
</li>
)
},
render: function(){
var orderIds = Object.keys(this.props.order);
var total = orderIds.reduce((prevTotal, key)=>{
var fish = this.props.fishes[key];
var count = this.props.order[key];
var isAvailable = fish && fish.status === 'available';
if(isAvailable) {
return prevTotal + (count * parseInt(fish.price) || 0);
}
return prevTotal;
}, 0);
return (
<div className="order-wrap">
<h2 className="order-title">Your Order</h2>
<ul className="order">
{ orderIds.length > 0 ? orderIds.map(this.renderOrder) : ""}
<li className="total">
<strong>Total:</strong>
{helpers.formatPrice(total)}
</li>
</ul>
</div>
)
}
});
Order 的属性应该包括:可用的鱼及其所有详细信息、带有鱼 ID 和数量的当前订单以及 removeFromOrder 回调。当我探索 React 开发工具中的组件时,它拥有所有这些东西。
当我用道具警报替换 removeFromOrder 回调时,会发生什么:
- 点击,什么都没有
- 在页面刷新时,弹出两个警告:第一个提示包括当前订单和一个空的 fishes 数组,第二个提示包括当前订单和已填充的 fishes 数组。两者都没有显示 removeFromOrder 回调函数,从事件侦听器的角度来看,它似乎是未定义的。
关于一个可能相关的说明,当我在 React 开发工具中浏览组件并将鼠标悬停在订单中的列表项上时,我收到以下错误:TypeError: node.getBoundingClientRect is not a function
。我不确定这是否是我问题的一部分;如果不是,我不太关心它,因为它似乎只在我将鼠标悬停在开发工具中的元素上时才会弹出。
感谢您阅读这篇长文,如有任何帮助,我们将不胜感激!
正如@azium 指出的那样,问题是一个简单的错字:onCLick={alert()}
应该是 onClick={() => alert()}
。捂脸。
我相信我有两个基本问题,它们可能是相关联的。我试图在嵌套组件上放置一个带有回调函数的事件处理程序。它似乎没有做任何事情,所以我用 JSON.stringify(this.props)
的警报替换了回调函数,看看这是否会有所帮助。它说明了两个问题:1)我的回调函数不在道具中。 2) 警报在页面加载时弹出 2 次,但没有像预期的那样在点击时弹出。我正在处理 this React tutorial。以下是相关组件:
var App = React.createClass({
mixins: [Catalyst.LinkedStateMixin],
getInitialState: function(){
return {
fishes: {},
order: {}
}
},
componentDidMount: function(){
base.syncState(this.props.params.storeId + '/fishes', {
context: this,
state: 'fishes'
});
var localStorageRef = localStorage.getItem('order-' + this.props.params.storeId);
if(localStorageRef){
this.setState({
order: JSON.parse(localStorageRef)
});
}
},
componentWillUpdate: function(nextProps, nextState){
localStorage.setItem('order-' + this.props.params.storeId, JSON.stringify(nextState.order));
},
loadSamples: function(){
this.setState({
fishes: require('./sample-fishes.js')
});
},
addFish: function(fish){
var timestamp = (new Date()).getTime();
this.state.fishes['fish-' + timestamp] = fish;
this.setState({ fishes: this.state.fishes });
},
removeFish: function(key){
if(confirm("Are you sure you want to remove this fish?")){
this.state.fishes[key] = null;
this.setState({ fishes: this.state.fishes });
}
},
addToOrder: function(key){
this.state.order[key] = this.state.order[key] + 1 || 1;
this.setState({ order: this.state.order });
},
// <<<<<<<< the function I'm having trouble with >>>>>>>>
removeFromOrder: function(key){
alert('hi');
delete this.state.order[key];
this.setState({ order: this.state.order });
},
renderFish(key){
return <Fish key={key} index={key} details={this.state.fishes[key]} addToOrder={this.addToOrder}/>
},
render: function(){
return (
<div className="catch-of-the-day">
<div className="menu">
<Header tagline="Fresh Seafood Market"/>
<ul className="list-of-fish">
{/*{ Object.keys(this.state.fishes).map(this.renderFish) }*/}
{ Object.keys(this.state.fishes).length > 0 ? Object.keys(this.state.fishes).map(this.renderFish) : <li>No Fishes!</li> }
</ul>
</div>
// <<<<<<<< I pass the function through to the Order component >>>>>>>>
<Order fishes={this.state.fishes} order={this.state.order} removeFromOrder={this.removeFromOrder}/>
<Inventory fishes={this.state.fishes} addFish={this.addFish} removeFish={this.removeFish} loadSamples={this.loadSamples} linkState={this.linkState}/>
</div>
)
}
});
var Order = React.createClass({
renderOrder: function(key){
var fish = this.props.fishes[key];
var count = this.props.order[key];
// <<<<<<<< the onClick I'm having trouble with >>>>>>>>
var removeButton = <button onCLick={this.props.removeFromOrder.bind(null, key)}>×</button>
// var removeButton = <button onCLick={alert(JSON.stringify(this.props))}>×</button>
if(!fish) {
return <li key={key}>Sorry, that fish is no longer available! {removeButton}</li>
// return <li key={key}>Sorry, that fish is no longer available!</li>
}
return (
<li key={key}>
{count}lbs
{" " + fish.name}
<span className="price">{helpers.formatPrice(count * fish.price)} {removeButton}</span>
{/*<span className="price">{helpers.formatPrice(count * fish.price)}</span>*/}
</li>
)
},
render: function(){
var orderIds = Object.keys(this.props.order);
var total = orderIds.reduce((prevTotal, key)=>{
var fish = this.props.fishes[key];
var count = this.props.order[key];
var isAvailable = fish && fish.status === 'available';
if(isAvailable) {
return prevTotal + (count * parseInt(fish.price) || 0);
}
return prevTotal;
}, 0);
return (
<div className="order-wrap">
<h2 className="order-title">Your Order</h2>
<ul className="order">
{ orderIds.length > 0 ? orderIds.map(this.renderOrder) : ""}
<li className="total">
<strong>Total:</strong>
{helpers.formatPrice(total)}
</li>
</ul>
</div>
)
}
});
Order 的属性应该包括:可用的鱼及其所有详细信息、带有鱼 ID 和数量的当前订单以及 removeFromOrder 回调。当我探索 React 开发工具中的组件时,它拥有所有这些东西。
当我用道具警报替换 removeFromOrder 回调时,会发生什么: - 点击,什么都没有 - 在页面刷新时,弹出两个警告:第一个提示包括当前订单和一个空的 fishes 数组,第二个提示包括当前订单和已填充的 fishes 数组。两者都没有显示 removeFromOrder 回调函数,从事件侦听器的角度来看,它似乎是未定义的。
关于一个可能相关的说明,当我在 React 开发工具中浏览组件并将鼠标悬停在订单中的列表项上时,我收到以下错误:TypeError: node.getBoundingClientRect is not a function
。我不确定这是否是我问题的一部分;如果不是,我不太关心它,因为它似乎只在我将鼠标悬停在开发工具中的元素上时才会弹出。
感谢您阅读这篇长文,如有任何帮助,我们将不胜感激!
正如@azium 指出的那样,问题是一个简单的错字:onCLick={alert()}
应该是 onClick={() => alert()}
。捂脸。