组件在React中没有响应

时间:2019-01-06 20:31:13

标签: javascript reactjs components render jsx

我的一个组件出现了一些问题。在我的程序中,我有我的App组件,它是父组件。其中包含称为按钮和输入的组件。在我的程序中,您必须单击按钮之一,这些按钮由renderButtons()函数渲染以安装Inputs组件。单击其中一个按钮时,将运行onSubmit()函数,并且createTextBoxes()函数将同时运行。简而言之,onSubmit()会更改状态中的“索引”键,并且当createTextBoxes()意识到“索引”已更改时,它将安装Inputs组件。

App.js代码如下所示:

import React, { Component } from "react";
import "./App.css";
import Button from "./Button";
import Inputs from "./Inputs";
class App extends Component {
  state = {
    index: "",
    buttons: [
      { value: "Algebra 2 Honors", classes: "primary" },
      { value: "British Literature", classes: "success" },
      { value: "Chemistry Honors", classes: "danger" },
      { value: "Modern European History", classes: "warning" },
      { value: "Spanish II", classes: "secondary" },
      { value: "Health Upper School", classes: "info" }
    ],
    textBoxes: [
      {
        identification: "Algebra 2 Honors",
        categories: [
          { Homework: 25 },
          { Notebook: 5 },
          { Quizzes: 20 },
          { Tests: 50 }
        ]
      },
      {
        identification: "British Literature",
        categories: [{ Assessments: 90 }, { Participation: 10 }]
      },
      {
        identification: "Chemistry Honors",
        categories: [
          { Homework: 25 },
          { Labreports: 34 },
          { Quizzes: 10 },
          { Tests: 31 }
        ]
      },
      {
        identification: "Modern European History",
        categories: [
          { Homework: 30 },
          { Participation: 10 },
          { Quizzes: 20 },
          { Tests: 40 }
        ]
      },
      {
        identification: "Spanish II",
        categories: [
          { Participation: 25 },
          { Projects: 25 },
          { Tests: 15 },
          { Assessments: 35 }
        ]
      },
      {
        identification: "Health Upper School",
        categories: [
          { Project: 33.333 },
          { Participation: 33.333 },
          { Quizzes: 33.333 }
        ]
      }
    ]
  };

  renderButtons = () => {
    var list = [];
    for (var i = 0; i < this.state.buttons.length; i++) {
      const id = this.state.buttons[i].classes;
      list.push(
        <Button
          key={id}
          className={id}
          value={this.state.buttons[i].value}
          eventHandler={() => this.onSubmit(id)}
        />
      );
    }
    return list;
  };

  onSubmit = id => {
    const buttonType = id;
    var index = null;
    if (id === "primary") {
      index = 0;
    } else if (id === "success") {
      index = 1;
    } else if (id === "danger") {
      index = 2;
    } else if (id === "warning") {
      index = 3;
    } else if (id === "secondary") {
      index = 4;
    } else if (id === "info") {
      index = 5;
    }
    console.log("The button that has been clicked has an index of " + index);
    this.setState({ index });
  };

  createTextBoxes = () => {
    if (this.state.index !== "") {
      const index = parseInt(this.state.index);
      const indexPhrase = this.state.textBoxes[index];
      console.log(indexPhrase);
      return <Inputs teamState={indexPhrase} />;
    } else {
      console.log("Wait for the click of a button");
    }
  };

  render() {
    return (
      <div className="App">
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
          integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
          crossOrigin="anonymous"
        />
        <script
          src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
          integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
          crossOrigin="anonymous"
        />
        <script
          src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
          integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
          crossOrigin="anonymous"
        />
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
          integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
          crossOrigin="anonymous"
        />
        <h1 className="text-white">
          <u>Subject Grade Calculator!</u>
        </h1>
        <br />
        <br />
        {this.renderButtons()}
        {this.createTextBoxes()}
        {/* {this.resetIndex()} */}
      </div>
    );
  }
}
export default App;

Button.js代码如下所示:

import React, { Component } from "react";
import "./App.css";

class Button extends Component {
  state = {
    class: "btn btn-" + this.props.className,
    value: this.props.value,
    eventHandler: this.props.eventHandler
  };

  render() {
    return (
      <div className="App">
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
          integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
          crossorigin="anonymous"
        />
        <script
          src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
          integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
          crossorigin="anonymous"
        />
        <script
          src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
          integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
          crossorigin="anonymous"
        />
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
          integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
          crossorigin="anonymous"
        />
        <input
          type="button"
          name="0"
          value={this.state.value}
          className={this.state.class}
          onClick={this.state.eventHandler}
        />
      </div>
    );
  }
}

export default Button;

最后,这是Inputs.js代码:

import React, { Component } from "react";
import "./App.css";

class Inputs extends Component {
  state = {
    title: this.props.teamState.identification,
    caption:
      "Enter your information below when the text boxes prompt you to do so:"
  };

  render() {
    return (
      <div className="App">
        <link
          rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
          integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
          crossorigin="anonymous"
        />
        <script
          src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
          integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
          crossorigin="anonymous"
        />
        <script
          src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
          integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
          crossorigin="anonymous"
        />
        <script
          src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
          integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
          crossorigin="anonymous"
        />
        {console.log(this.state.object)}
        <br />
        <br />
        <h3 className="text-white">{this.state.title}</h3>
        <br />
        <h4 className="text-white">{this.state.caption}</h4>
        <br />
        <br />
      </div>
    );
  }
}

export default Inputs;

这很好,但是,如果再次单击另一个按钮,则不会装入具有不同属性的新Inputs组件。

任何人都可以解释为什么createTextBoxes()不能更改正在渲染的组件,以及我该怎么做吗?

1 个答案:

答案 0 :(得分:0)

当然,作为一个初学者,我并没有真正考虑过生命周期挂钩和其他可用功能。我需要做的就是使用componentWillReceiveProps()函数,该函数将在新道具传递到Inputs Component本身时允许React更新状态。这是Inputs组件的更新代码:

import React, { Component } from "react";
import "./App.css";

class Inputs extends Component {
  state = {
    title: this.props.teamState.identification,
    caption:
      "Enter your information below when the text boxes prompt you to do so:"
  };

  componentWillReceiveProps(nextProps) {
    if (this.props !== nextProps) {
      this.setState({ title: nextProps.teamState.identification });
    }
  }

  render() {
    return (
      <div className="App">
        {console.log(this.state)}
        <br />
        <br />
        <h3 className="text-white">{this.state.title}</h3>
        <br />
        <h4 className="text-white">{this.state.caption}</h4>
        <br />
        <br />
      </div>
    );
  }
}

export default Inputs;

我已按照用户jonrsharpe的要求或建议删除了bootstrap,jquery和popper链接。但是,此功能在React的版本17中将不可用,因此建议改用UNSAFE_componentWillReceiveProps()。这是我找出此信息的链接:1谢谢!