将props传递给动态子组件

时间:2017-09-02 04:53:21

标签: javascript reactjs

我正在尝试创建一个多步骤表单。我创建了表单,在每个步骤中,动态呈现相应的表单。但我不知道如何将道具传递给那些组件,以便在返回时,状态得到保留。我在codesandbox中创建了一个沙箱,这里是

http://jsfiddle.net/Eh2ym/

表单的呈现按以下方式完成

{this.props.steps[this.state.componentState].component}

如果组件呈现如下,这是静态方式,代码将是这样的,但我想要动态的方式

if(this.state.componentState === 1) {
 <Form1 props={props} />
}

代码是

import React from 'react';
import './fullscreenForm.css';

class MultipleForm extends React.PureComponent {
  constructor(props) {
    super(props);
    this.hidden = {
      display: "none"
    };
    this.state = {
      email: 'steve@apple.com',
      fname: 'Steve',
      lname: 'Jobs',
      open: true,
      step: 1,
      showPreviousBtn: false,
      showNextBtn: true,
      componentState: 0,
      navState: this.getNavStates(0, this.props.steps.length)
    };
  }

  getNavStates(indx, length) {
    let styles = [];
    for (let i = 0; i < length; i++) {
      if (i < indx) {
        styles.push("done");
      } else if (i === indx) {
        styles.push("doing");
      } else {
        styles.push("todo");
      }
    }
    return { current: indx, styles: styles };
  }

  checkNavState(currentStep) {
    if (currentStep > 0 && currentStep < this.props.steps.length) {
      this.setState({
        showPreviousBtn: true,
        showNextBtn: true
      });
    } else if (currentStep === 0) {
      this.setState({
        showPreviousBtn: false,
        showNextBtn: true
      });
    } else {
      this.setState({
        showPreviousBtn: true,
        showNextBtn: false
      });
    }
  }

  setNavState(next) {
    this.setState({
      navState: this.getNavStates(next, this.props.steps.length)
    });
    if (next < this.props.steps.length) {
      this.setState({ componentState: next });
    }
    this.checkNavState(next);
  }

  next = () => {
    this.setNavState(this.state.componentState + 1);
  };

  previous = () => {
    if (this.state.componentState > 0) {
      this.setNavState(this.state.componentState - 1);
    }
  };

  render() {
    return (
      <div className="parent-container">
        <div className="form-block">
        {this.props.steps[this.state.componentState].component}
        </div>
        <div 
          className="actions" 
          style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'flex-end'}}
          >
          <button
            style={this.state.showPreviousBtn ? {} : this.hidden}
            className="btn-prev"
            onClick={this.previous}
          >
            Back
          </button>

          <button
            style={this.state.showNextBtn ? {} : this.hidden}
            className="btn-next"
            onClick={this.next}
          >
            Continue
          </button>
        </div>
      </div>
    );
  }
}

export default MultipleForm;

我想以最佳实践方式。

1 个答案:

答案 0 :(得分:1)

您需要为所有步骤输入保存表单的值。现在,因为在每一步都要更改表单组件,所以不能将这些值放在相应的表单组件中。因此,您必须将这些值放在父容器中(即MultipleForm)。现在,当您在父容器中维护子组件的值状态时,您必须设置某种机制,以便每当子组件中的输入发生任何更改时,它应该更新父容器中的相应状态。为此,您可以将更改处理函数传递给子组件。所以你的表单组件看起来应该是这样的

<div className="fullscreen-form">
        <div className="custom-field">
          <label className="custom-label fs-anim-upper" for="email">
            What's your email address?
          </label>
          <input
            className="fs-anim-lower"
            id="email"
            name="email"
            type="email"
            onChange={this.props.handleChange} // Whenver the input changes then call the parent container's handleChange function so that it can update it's state accordingly
            value={this.props.value} // Updated value passed from parent container
            placeholder="steve@apple.com"
          />
        </div>
      </div>

你会像这样呈现你的表格

<Form1 handleChange={this.handleChange} value={this.state.email} />

以下是您的代码:: Code

的可行解决方案