在渲染方法中设置状态 - Reactjs

pra*_*esh 2 reactjs

我有一个包含几个问题的表格。一些问题有一组子问题。这些是使用以下代码呈现的。

    {
  Object.keys(this.props.moduleDetails.questions).map((questionInfo, index) => (
    <div key={index}>
      <QuestionAnswers
        questionInfo={this.props.moduleDetails.questions[questionInfo]}
        generateStepData={this.props.generateStepData}
        states={this.props.states}
        userEnteredValues={this.props.formValues}
        errors={this.props.errors}
        setQuestionAnswers={this.setQuestionAnswers}
      />
      {this.props.moduleDetails.questions[questionInfo].question_group &&
      this.props.moduleDetails.questions[questionInfo].has_grouped_questions ===
        1 ? (
        <div className="sub-questions">
          {this.props.moduleDetails.questions[questionInfo].question_group ? (
            <span>
              {this.renderQuestionGroup(questionInfo)}
              <input
                type="button"
                onClick={e => {
                  this.addQuestionGroup(questionInfo)
                }}
                value="Add"
                className="btn"
              />
            </span>
          ) : null}
        </div>
      ) : null}
    </div>
  ))
}
Run Code Online (Sandbox Code Playgroud)

如您所见,问题组是使用 renderQuestionGroup(questionInfo) 方法呈现的。

renderQuestionGroup(questionInfo) {
    let input = [];
    this.state.groupedQuestions[questionInfo] = (this.state.groupedQuestions[questionInfo]) ?
                    this.state.groupedQuestions[questionInfo]
                    : [];
    let answerId = this.props.formValues[questionInfo];
    let groupedQuestions = this.props.moduleDetails.questions[questionInfo].question_group[answerId];
    if((groupedQuestions != null && this.state.groupedQuestions[questionInfo].length == 0) || this.state.isAddPressed) {
        this.state.groupedQuestions[questionInfo].push(groupedQuestions);

    }
    input = this.display(questionInfo)
    return input;
  }
Run Code Online (Sandbox Code Playgroud)

这里的问题是我不能在这个方法中设置状态,因为这个方法在 render 方法中被调用

关于如何解决这个问题的任何想法?

有没有其他方法可以解决这个问题?

Aum*_*kur 10

您不能在渲染函数中设置状态,因为它会导致副作用。

真正发生的事情是每次更新状态时,react 都会调用渲染函数,所以如果你在渲染函数中更新状态,那么它就会陷入无限循环。

一般来说,这永远不应该发生;您不应该做任何与在渲染函数中修改任何组件状态相关的远程操作。


lay*_*nez 6

您需要将设置状态逻辑移动到

 componentDidUpdate(prevProps, prevState, snapshot) {
        if (prevPros.prop !=== this.props.prop) {
          /* your setState logic*/
        }
      }
Run Code Online (Sandbox Code Playgroud)

然后只需staterenderQuestionGroup.

也永远不要直接修改状态:

this.state.groupedQuestions[questionInfo] = (this.state.groupedQuestions[questionInfo]) ?
                this.state.groupedQuestions[questionInfo]
                : [];
Run Code Online (Sandbox Code Playgroud)

setState({groupedQuestions: [...groupedQuestions,updatedGroup })

来自反应设置状态文档

永远不要直接改变 this.state,因为之后调用 setState() 可能会替换你所做的改变。将 this.state 视为不可变的。

setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。

无法保证对 setState 调用的同步操作,并且可能会批量调用以提高性能。

除非在 shouldComponentUpdate() 中实现了条件渲染逻辑,否则 setState() 将始终触发重新渲染。如果正在使用可变对象并且无法在 shouldComponentUpdate() 中实现逻辑,则仅在新状态与先前状态不同时调用 setState() 将避免不必要的重新渲染。