使用状态将数据从子级传递到父级。

时间:2018-10-02 12:51:40

标签: javascript reactjs

我是react js的新手。这可能是一个简单的问题,但我没有办法解决。所以,我在问这个问题。

我有一个 grandParentComp ,就像

GrandParent

import React from 'react';

class QuizSetupMain extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            technologies: this.props.technologies,
            hasError: false
        }
    }
render() {
        return (

            <div >
            {this.state.technologies.length > 0 ? <LowLevelCriteria techData={this.state.technologies} /> : null}

    <div className="fetchBtnDiv mx-auto">
                    <button className="btn btn-primary fetchBtnSize" disabled={this.state.hasError}>Fetch Questions</button>
                </div>
</div>

Herem,我有要根据状态变量禁用的按钮

LowCriteria.js ,这是孩子

从'react'导入React;

class LowLevelCriteria extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            technologies: this.props.techData,
            lowData: this.props.lowData.low,
            hasError: false
        }
    }

  componentWillReceiveProps(nextProps) {
        if (nextProps.lowData.Low.length > 0) {
            console.log("in this");
            var previous_data = nextProps.lowData;
            var i = 0;
            previous_data.Low.map((object) => {
                i = i + parseInt(object.numberOfQuestions);
            });
            console.log("value of i is ==>", i);
            if (i >= 6) {
                this.setState({
                    hasError: true
                })
            } else {
                this.setState({
                    hasError: false
                })
            }
        }
    }

  render() {
        return (
            <div>
                <div className="questionLevelIndication">
                    <span className="levelIndicatorBtn backgroundColorForLow">
                        1
                    </span>
                    <label className="levelIndicationLabel">
                        Low Difficulty Level - Maximum 6 questions
                    </label>
                    {this.state.hasError && <div class="alert alert-danger alert-dismissible fade show">
                        <button type="button" class="close" data-dismiss="alert">&times;</button>
                        <strong>Please reduce number of questions</strong>
                    </div>}
                </div>
                {(this.props.lowData) && this.props.lowData.Low.length > 0 && this.props.lowData.Low.map(data => (
                    <LowRow technologies={this.state.technologies} hasError={this.state.hasError} onChange={this.onchange.bind(this)} data={data} key={data.id} onAddRow={this.onaddRow.bind(this)} onRemoveRow={this.onRemoveRow.bind(this)} />
                ))}
            </div>
        )
    }

因此,现在我想将此this.state.hasError传递给父级,以便可以禁用父级组件上的按钮。

我不想使用redux。

有人可以帮我吗?

我没有要从子函数调用的任何按钮或函数。因此我可以更新父状态。

2 个答案:

答案 0 :(得分:0)

您不能直接从子组件更新父状态。最好的选择是创建一个处理函数,该处理函数传递给居住在父级上的子级,以更新父级的状态。

答案 1 :(得分:0)

您需要一个回调函数来处理此问题。按照下面的建议进行操作

在您的GrandParent组件中,声明该组件内部的处理函数,并将标志设置为hasError。此标志是布尔值,您将从子组件的回调函数中收到

 handleHasError = flag => {
      this.setState({
          hasError: flag
      });
 }

将handleHasError传递给LowLevelCriteria,例如

     {this.state.technologies.length > 0 ? <LowLevelCriteria techData={this.state.technologies} handleHasError={this.handleHasError}/> : null}

在LowLevelCriteria组件中,调用this.props.handleHasError函数,如下所示

  if (i == 6) {
            this.setState({
                hasError: true
            })
           this.props.handleHasError(true);
        } else {
            this.setState({
                hasError: false
            })
          this.props.handleHasError(false);
        }

通过此更改,按钮将按预期工作

编辑:

由于未将当前道具与nextProps进行比较,因此您超出了getMaximum更新深度。您直接在做setState,所以需要比较它们,然后再做setState

  componentWillReceiveProps(nextProps) {
     if(nextProps.lowData != this.props.lowData){
    if (nextProps.lowData.Low.length > 0) {
        console.log("in this");
        var previous_data = nextProps.lowData;
        var i = 0;
        previous_data.Low.map((object) => {
            i = i + parseInt(object.numberOfQuestions);
        });
        console.log("value of i is ==>", i);
        if (i == 6) {
            this.setState({
                hasError: true
            })
        this.props.handleHasError(true);
        } else {
            this.setState({
                hasError: false
            })
        this.props.handleHasError(false);
        }
    }
   }
  }

如果有错字,请原谅,因为我正在用手机接听电话