多步骤表单:无法在已卸载的组件上调用setState(或forceUpdate)

时间:2018-10-12 06:18:25

标签: javascript reactjs

我正在尝试创建一个多步骤表单。在第一步,它将选择接下来要渲染的组件。但是,Warning: Can't call setState (or forceUpdate) on an unmounted component.出现了。 搜索大多数类似的问题,但没有一个适合我的情况。我的代码如下

Index.js是一个容器,用于根据对Step1.js的选择来呈现不同的组件

调用SetFlags时发生错误

Step1.js

import React, { Component } from 'react';
import { AvForm, AvField, AvGroup, AvInput, AvFeedback, AvRadioGroup, AvRadio } from 'availity-reactstrap-validation';
import {
  Button,
  Card,
  CardBody,
  CardHeader,
  CardFooter,
  Col,
  Label,
  Row,
} from 'reactstrap';


class StudentRegistrationStep1 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isSubmitting: false,
      isExistingUser: null,
    };
  }

  handleSubmit = (event, errors, values) => {
    event.preventDefault();
    const { isExistingUser } = this.state;
    const { setFlags } = this.props;
    let step = 2.1;
    if (isExistingUser === 1) {
      step = 2.2;
    }
    setFlags(step);
  }

  render() {
    return (
      <div className="animated fadeIn">
        <Row>
          <Col xs="12" sm={{ size: 6, offset: 3 }}>
            <AvForm onSubmit={this.handleSubmit}>
              <Card>
                <CardHeader>
                  <strong>New registration</strong>
                </CardHeader>
                <CardBody>
                  <AvRadioGroup name="isExistingUser" required>
                    <AvRadio customInput label="Exisitng Academeet user/ new family member" value="0" onChange={() => { this.setState({ isExistingUser: 1 }); }} />
                    <AvRadio customInput label="New user" value="1" onChange={() => { this.setState({ isExistingUser: 0 }); }} />
                  </AvRadioGroup>
                </CardBody>
                <CardFooter>
                  <Button color="primary" type="submit" className="pull-right">
                    Next step
                    {' '}
                    <i className="fa fa-arrow-circle-right" />
                  </Button>
                </CardFooter>
              </Card>
            </AvForm>
          </Col>
        </Row>
      </div>
    );
  }
}

export default StudentRegistrationStep1;

Index.js

import React, { Component } from 'react';
import { AvForm, AvField, AvGroup, AvInput, AvFeedback, AvRadioGroup, AvRadio } from 'availity-reactstrap-validation';
import {
  Button,
  Card,
  CardBody,
  CardHeader,
  CardFooter,
  Col,
  Label,
  Row,
} from 'reactstrap';
import Step1 from './Step1';
import Registration from './Registration';
import ExistingUser from './ExistingUser';
import ClassAssignment from './ClassAssignment';

class StudentRegistration extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isSubmitting: false,
      currentStep: 1,
      isExistingUser: false,
      isCreateNewFamily: false,
      isCreateNewUser: false,
      currentComponent: <Step1 setFlags={this.setFlags} />,
    };
  }

  changeStep = (step) => {
    const { currentStep } = this.state;
    let component = <Step1 setFlags={this.setFlags} />;
    switch (currentStep) {
      case 2.1:
        // New user
        component = <Registration setFlags={this.setFlags} />;
        break;
      case 2.2:
        // Exisiting user
        component = <ExistingUser setFlags={this.setFlags} />;
        break;
      case 3:
        component = <ClassAssignment setFlags={this.setFlags} />;
        break;
      default:
        component = <Step1 setFlags={this.setFlags} />;
    }
    this.setState({ currentComponent: component });
    return component;
  }

  setFlags = (step) => {
    this.setState({ currentStep: step }, () => {
      this.changeStep();
    });
  }

  render() {
    const { currentComponent } = this.state;
    return (
      <div>
        {currentComponent}
      </div>

    );
  }
}

export default StudentRegistration;

赞赏(鞠躬)

1 个答案:

答案 0 :(得分:0)

您无需将组件存储在状态下,因为它可以从currentStep状态派生而来,这可能会导致您的情况减弱

import React, { Component } from 'react';
import { AvForm, AvField, AvGroup, AvInput, AvFeedback, AvRadioGroup, AvRadio } from 'availity-reactstrap-validation';
import {
  Button,
  Card,
  CardBody,
  CardHeader,
  CardFooter,
  Col,
  Label,
  Row,
} from 'reactstrap';
import Step1 from './Step1';
import Registration from './Registration';
import ExistingUser from './ExistingUser';
import ClassAssignment from './ClassAssignment';

class StudentRegistration extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isSubmitting: false,
      currentStep: 1,
      isExistingUser: false,
      isCreateNewFamily: false,
      isCreateNewUser: false,
      currentComponent: <Step1 setFlags={this.setFlags} />,
    };
  }

  renderStep = (step) => {
    const { currentStep } = this.state;
    let component = <Step1 setFlags={this.setFlags} />;
    switch (currentStep) {
      case 2.1:
        // New user
        component = <Registration setFlags={this.setFlags} />;
        break;
      case 2.2:
        // Exisiting user
        component = <ExistingUser setFlags={this.setFlags} />;
        break;
      case 3:
        component = <ClassAssignment setFlags={this.setFlags} />;
        break;
      default:
        component = <Step1 setFlags={this.setFlags} />;
    }
    return component;
  }

  setFlags = (step) => {
    this.setState({ currentStep: step });
  }

  render() {
    return (
      <div>
        {this.renderStep()}
      </div>

    );
  }
}

export default StudentRegistration;