渲染方法中的setstate-React.js

时间:2018-07-05 10:55:31

标签: 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>
                  )
              }

如您所见,问题组是使用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;
  }

这里的问题是,我无法在此方法内设置状态,因为此方法在渲染方法内称为

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

有其他替代方法吗?

2 个答案:

答案 0 :(得分:2)

您需要将设置状态逻辑移至

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

然后只需在state中使用修改后的renderQuestionGroup

也永远不要直接使用以下方法修改状态:

this.state.groupedQuestions[questionInfo] = (this.state.groupedQuestions[questionInfo]) ?
                this.state.groupedQuestions[questionInfo]
                : [];

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

from react set state docs

  

从不直接更改this.state,因为之后可能会调用setState()   替换您所做的突变。将this.state视为   不变的。

     

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

     

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

     

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

答案 1 :(得分:1)

您不能在渲染函数中设置状态,因为这会引起副作用。

真正发生的是,每次更新状态时,反应都会调用渲染函数,因此,如果要在渲染函数中更新状态,则会陷入无限循环。

通常,这种情况永远不会发生;您不应该在渲染功能中进行任何与修改任何组件状态有关的远程操作。