React onClick在加载时多次触发,并且在组件props中不包含回调函数

时间:2016-05-01 16:10:18

标签: reactjs callback onclick event-handling components

我相信我有两个基本问题,可能是相关的。我正在尝试在嵌套组件上放置一个带回调函数的事件处理程序。它似乎没有做任何事情,所以我用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)}>&times;</button>
    // var removeButton = <button onCLick={alert(JSON.stringify(this.props))}>&times;</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 dev工具中探索组件时,它具有所有这些功能。

当我用道具警告替换removeFromOrder回调时,会发生什么: - 点击,没有 - 在页面刷新时,弹出两个警报:第一个中的道具包括当前订单和空鱼类数组,第二个中的道具包括当前订单和填充的鱼类数组。都没有显示removeFromOrder回调函数,它从事件监听器的角度看似未定义。

在一个可能相关的说明中,当我在React dev工具中浏览组件并将鼠标悬停在Order中的列表项时,我收到以下错误:TypeError: node.getBoundingClientRect is not a function。我不确定这是否是我问题的一部分;如果不是,我不太关心它,因为当我将鼠标悬停在开发工具中的元素上时,它似乎只会弹出。

感谢您阅读这篇长篇文章,非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

正如@azium所指出的,问题是一个简单的错字:onCLick={alert()}应该是onClick={() => alert()}。捂脸。