【问题标题】:calling function in if statement inside map in react在地图内的if语句中调用函数反应
【发布时间】:2019-07-08 00:03:32
【问题描述】:

我试图映射一个数组,该数组由 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:我使用的是基于类的组件而不是功能组件

【问题讨论】:

  • 您需要比“它不起作用”更具体一些 - 您是否收到错误消息?你想调用什么函数?您希望发生的事情不是?
  • 我不认为它只是没有被调用!
  • 再说一遍,什么功能?
  • 在 if 语句中表示 this.DOSOMETHING 的函数。我希望它调用我在渲染之外定义的函数
  • 我可以看到你试图在哪里调用它......我的意思是,它没有在示例中的任何地方声明 - 你在哪里声明DOSOMETHING

标签: reactjs render


【解决方案1】:

发生递归是因为您总是map 中调用setState,并且如果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);
  ...
}

事实上,尽管您不能在render 期间致电setState,但已经说过这不起作用。如果您将其移至componentDidMount / componentDidUpdate,这一切都会变得容易得多

setQuestion() {
  const questionId = this.props.quiz.question_sets[this.state.currentStep];
  this.setState({ questionId });
}

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

【讨论】:

  • @NSJCorps 第二个示例可能更适合您,因为假设您有各种要触发重新渲染的属性/状态,这只是向您展示如何阻止的示例额外的渲染
  • 地图回调放哪里
  • @NSJCorps 嗯?示例中的代码将替换地图回调函数中现有的 if - 为简洁起见,我省略了其他代码。
  • 如何添加回调
  • 现在它可以工作了,但我收到了这个错误react-dom.development.js:506 Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
猜你喜欢
  • 2022-01-19
  • 2019-04-19
  • 1970-01-01
  • 2021-12-06
  • 2020-12-20
  • 1970-01-01
  • 2016-10-22
  • 1970-01-01
  • 2020-07-05
相关资源
最近更新 更多