代码之家  ›  专栏  ›  技术社区  ›  prajeesh

呈现方法内部的setstate-Reactjs

  •  0
  • prajeesh  · 技术社区  · 7 年前

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

        {
      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) {
        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;
      }
    

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

    有什么办法解决这个问题吗?

    2 回复  |  直到 5 年前
        1
  •  4
  •   layonez    7 年前

    不能在呈现函数中设置状态,因为这会产生副作用。

    确切的情况是,每次更新state react时都会调用render函数,所以如果您要在render函数中更新state,那么它将卡在无限循环中。

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

        2
  •  3
  •   layonez    7 年前

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

     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 :

    永不变异这个州直接调用setState()可以 替换你所做的突变。款待这个州好像是的

    setState()不会立即变化这个州但却产生了 挂起状态转换。访问这个州打电话后

    无法保证调用setState的同步操作 为了提高性能,可以对调用进行批处理。

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