ReactJS:在子组件中使用一个按钮会禁用第二个按钮?

时间:2018-01-28 17:19:54

标签: reactjs

我正在构建一个简单的食谱框,人们可以在其中添加食谱,它将保存到localStorage。目前我有一个弹出窗口,可以在其中添加食谱,然后保存。您可以看到以下界面:

Current Codepen

当我按下“关闭我”按钮时,我可以根据需要在主屏幕和弹出窗口之间切换。但是,如果我首先单击“添加配方”,则“关闭我”按钮将不再起作用并触发错误:(父组件中的this.setState)未定义。

非常感谢有关为何发生这种情况以及如何解决问题的任何信息。

以下是Codepen的链接:https://codepen.io/lieberscott/pen/JpPbZd?editors=0110

这是我的代码。与此行为交互的两个类是Box类和Addpopup类:

class Mainbutton extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <button onClick={this.props.toggleClose}>
        Add recipe
      </button>
    );
  }
}

class Recipes extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isExpanded: false,
      height: 0
    }
  }

  handleToggle(e) {
    e.preventDefault();

    this.setState({
      isExpanded: !this.state.isExpanded,
      height: this.refs.inner.clientHeight
    });
  }

  render() {

    const currentHeight = this.state.isExpanded ? this.state.height : 0;

    const ingredients = this.props.item.ingredients.map(ingredient => {
      return (
        <div>
          {ingredient}
        </div>
        );
    });

    return (
      <div className="panel" onClick={(e) => this.handleToggle(e)}>
        <h4>{this.props.item.name}</h4>
        <div
          className="panel-collapse"
          style={{height: currentHeight + "px"}}>
          <div ref="inner">
            {ingredients}
          </div>
        </div>
      </div>
    );
  }
}

class Box extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      popup: true,
      items: [
        {
          name: "Tofu tacos",
          ingredients: [
            "Tofu",
            "Chili powder",
            "Onion",
            "Cumin",
            "Oregano",
            "Paprika",
            "Salt",
            "Pepper",
            "Taco shells",
            "Lettuce",
            "Mozarella cheese"
          ] // end of ingredients array
        }, // end of first item
        {
          name: "Spaghetti",
          ingredients: [
            "pasta",
            "sauce"
          ]
        } // end of second item
      ] // end of items array
    } // end of this.state
    this.togglePopup = this.togglePopup.bind(this);
    this.addRecipe = this.addRecipe.bind(this);
  } // end of constructor

  togglePopup() {
    console.log("close fired");
    this.setState({
      popup: !this.state.popup
    });
  }

  addRecipe(food) {
    console.log(food);
    let foods = this.state.items;
    this.setState = ({
      items: foods.push(food)
    });
    console.log(this.state.items);
  }

  render() {
    const allitems = this.state.items.map(oneitem => (
      <Recipes item={oneitem} />
    ));
    return (
      <div>
        {allitems}
        {this.state.popup ? <Addpopup addRecipe={this.addRecipe} closeMe={this.togglePopup} /> : null}
        <Mainbutton toggleClose={this.togglePopup}/>
      </div>
    );
  }
}

class Addpopup extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      food: ""
    };
    this.changeFood = this.changeFood.bind(this);
    this.addRec = this.addRec.bind(this);
  }

  changeFood(e) {
    this.setState({
      food: e.target.value
    });
    console.log(this.state.food);
  }

  addRec() {
    let food = this.state.food;
    this.props.addRecipe(food);
  }

  render() {
    return (
      <div className="popup">
        <div className="popup-inner">
          <input type="text" placeholder="Food" onChange={this.changeFood}></input><br/>
          <input type="text" placeholder="Ingredients (seperated by commas)"></input><br/>
          <button onClick={this.addRec}>Add recipe</button>
          <button onClick={this.props.closeMe}>close me</button>
        </div>
      </div>
    );
  }
}

class Headline extends React.Component {
  render() {
    return (
      <div>
        <h1>Recipes</h1>
        <br/>
      </div>
    );
  }
}

class App extends React.Component {
  render() {
    return (
      <div>
        <Headline />
        <Box />
      </div>
    );
  }
}

const app = document.getElementById("app");

ReactDOM.render(<App />, app);

1 个答案:

答案 0 :(得分:3)

当您点击Add Recipe按钮时,您将重新分配我认为是拼写错误的this.setState。在addRecipe功能中,您有以下行

this.setState = ({
  items: foods.push(food)
});

将此行更改为

this.setState({
   // Array.push return length of array. So use spread operator like this
   items: [...foods, food]
});