在地图中的if语句中调用react中的函数

时间:2019-07-08 00:03:32

标签: reactjs render

我试图映射一个由if-else语句的控件呈现的数组,但是我想在该if-else语句中调用一个函数,但是它不起作用。为什么?

import PropTypes from "prop-types";
import { connect } from "react-redux";
import { NavLink } from "react-router-dom";
import { getQuiz, sendResponse } from "../../actions/quizzes";
import Navbar from "../layout/navbar";

class QuizDetail extends Component {
  constructor(props) {
    super(props);
    this.state = {
      currentStep: 0,
      selectedOption: null,
      questionId: null
    };
  }

  static propTypes = {
    user: PropTypes.object.isRequired,
    quiz: PropTypes.object,
    getQuiz: PropTypes.func.isRequired,
    sendResponse: PropTypes.func.isRequired
  };
  onSubmit = e => {
    e.preventDefault();
    console.log("boulevard");
  };
  _setQuestion = questionId => {
    console.log("me");
    this.setState({ questionId });
  };
  handleOptionChange = changeEvent => {
    this.setState({
      selectedOption: parseInt(changeEvent.target.id, 10)
    });
  };
  _next = answerId => {
    let quiztaker = this.props.quiz.quiztakers_set[0].id;
    let answer = this.state.selectedOption;
    this.props.sendResponse(quiztaker, 1, 1);
    let currentStep = this.state.currentStep;
    let arrayLength = this.props.quiz.questions_count;
    currentStep =
      currentStep >= arrayLength - 1 ? arrayLength - 1 : currentStep + 1;
    this.setState({
      currentStep,
      selectedOption: null
    });
  };

  _prev = () => {
    let currentStep = this.state.currentStep;
    currentStep = currentStep <= 0 ? 0 : currentStep - 1;
    this.setState({
      currentStep
    });
  };

  componentWillMount() {
    this.props.getQuiz(this.props.match.params.slug);
  }
  render() {
    if (!this.props.quiz) {
      return <h1>LOADING...</h1>;
    }
    let icon_next =
      this.state.currentStep === this.props.quiz.questions_count - 1
        ? "fas fa-check"
        : "fas fa-angle-right";
    let icon_prev =
      this.state.currentStep === 0 ? "d-none" : "dir_control left";
    return (
      <Fragment>
        <Navbar />
        <div className="row question">
          <div className="card col-lg-8 col-md-8 mx-auto">
            {this.props.quiz.question_set.map((question, index) => {
              let { currentStep } = this.state;

              let style = {};
              if (currentStep === index) {
                () => this._setQuestion(question.id);
                style = {
                  display: "inline-block"
                };
              } else {
                style = {
                  display: "none"
                };
              }

              return (
                <div
                  className="card-body"
                  style={style}
                  key={question.id}
                  id={index}
                >
                  <form onSubmit={this.onSubmit}>
                    <h5 className="card-title">{question.label}</h5>
                    {question.answer_set.map(answer => {
                      return (
                        <div className="answers" key={answer.id}>
                          <input
                            type="radio"
                            name={answer.question}
                            id={answer.id}
                            value={answer.text}
                            checked={this.state.selectedOption === answer.id}
                            onChange={this.handleOptionChange}
                          />

                          <label htmlFor={answer.id}>{answer.text}</label>
                          <button
                            type="submit"
                            onClick={this._prev}
                            className={icon_prev}
                          >
                            <span className="fas fa-angle-left"></span>
                          </button>
                          <button
                            type="submit"
                            onClick={this._next}
                            className="dir_control right"
                          >
                            <span className={icon_next}></span>
                          </button>
                        </div>
                      );
                    })}
                  </form>
                </div>
              );
            })}
          </div>
        </div>
      </Fragment>
    );
  }
}

const mapStateToProps = state => ({
  user: state.auth.user,
  quiz: state.quizzes.quiz.quiz
});

export default connect(
  mapStateToProps,
  { getQuiz, sendResponse }
)(QuizDetail);

每当我尝试不使用任何参数时,它都可以正常工作,但是当我添加参数时,它根本不起作用。

使用react网站上的文档无济于事。我已经尽一切努力使这项工作。我也尝试了堆栈溢出很长时间,直到我决定自己问这个问题。

P / S:我使用的是基于类的组件,而不是功能组件

1 个答案:

答案 0 :(得分:0)

之所以发生递归,是因为您总是在setState中调用map,并且如果questionId相同,则不要告诉组件忽略重新渲染

shouldComponentUpdate(nextProps, nextState) {
  return this.state.questionId !== nextState.questionId;
}

或者,您可以在map回调中添加此保护

let { currentStep, questionId } = this.state;

if (currentStep === index && questionId !== question.id) {
  this._setQuestion(question.id);
  ...
}

事实上,说了这是不管用的,因为您在setState期间不能调用render。如果将其移至componentDidMount / componentDidUpdate

,这一切将变得更加容易。
setQuestion() {
  const questionId = this.props.quiz.question_sets[this.state.currentStep];
  this.setState({ questionId });
}

componentDidMount() {
  setQuestion();
}
componentDidUpdate() {
  setQuestion();
}