动态添加React组件

时间:2016-06-01 20:50:47

标签: javascript reactjs

CONTEXT

我正在尝试动态添加react组件中的输入字段,同时仍然跟踪父组件中的状态(稍后使用它们调用方法)。

问题

不确定如何处理:

  1. 无需在父组件中定义固定数量的状态(urlpath1urlpath2等)。
  2. 未在子组件中定义固定数量的<Input/>个子组件。
  3. 这是我的父组件 - 这个组件需要捕获子/孙组件的输入元素的状态(或值),无论我有多少这样的<Input>个字段。

    import AddConditionSelect from './AddConditionSelect.jsx';
    
    class AddConditionDashboard extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          //Form Steps States
          step: 1,
          //AddConditionSelect States
          conditionTitle: '',
          conditionType: ''
        };
        // bind the context for the user input event handler
        // so we can use `this` to reference `AddConditionDashboard`
        this.onUserInputChange = this.onUserInputChange.bind(this);
        this.onUserClick = this.onUserClick.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
      }
    
    //TODO: REFACTOR - Can we refactor both these events into one to be used?
      onUserInputChange(event) {
        this.setState({
         conditionTitle: event.target.value
        });
      }
    
      onUserClick(event) {
        this.setState({
          conditionType:event.target.value
        });
      }
    
      onSubmit(event) {
        event.preventDefault;
        const {create, segmentId} = this.props;
        const conditionTitle = this.state.conditionTitle;
        const conditionType = this.state.conditionType;
    
        create(conditionTitle, conditionType, segmentId);
        //TODO: CALLBACK IF STATEMENT - Check with a callback function if create ran sucessfully, only then do nextste();
    
        if (conditionType == 'urlPath') {
          this.setState({
              step: 21
            });
        } else if (conditionType == 'timeOnSite') {
          this.setState({
              step: 22
            });
        };
    
      }
    
      render() {
    
    
        const {error, segmentId} = this.props;
    
        switch (this.state.step) {
          //SELECT CONDITION
          case 1: return (
                    <div>
    
                    {error ? <Message inverted={true}  rounded={true}  theme="error">{error}</Message>  : null}
    
                  <AddConditionSelect
                    segmentId={segmentId}
                    onUserClick={this.onUserClick}
                    conditionTitle={this.state.conditionTitle}
                    onUserInputChange={this.onUserInputChange}
                  />
    
    
                  <PanelFooter theme="default">
                    <Button
                        backgroundColor="primary"
                        color="white"
                        inverted={true}
                        rounded={true}
                        onClick={(event) => this.onSubmit(event)}
                      >
                        Next Step
                    </Button>
                  </PanelFooter>
    
    
                    </div>
                  );
          //ADD URL PATH
          case 21: return (
                        <div>
    
                        <AddConditionCURLPath 'something here' />
    
                        <PanelFooter theme="default">
                          <Button
                              backgroundColor="primary"
                              color="white"
                              inverted={true}
                              rounded={true}
                              onClick={(event) => this.onSubmit(event)}
                            >
                              Next Step
                          </Button>
                        </PanelFooter>
    
                        </div>
    
                      );
    
            //ADD TIME ON SITE
            case 22: return (
                          <div>
    
                            <AddConditionSomethignElse  />
    
                          <PanelFooter theme="default">
                            <Button
                                backgroundColor="primary"
                                color="white"
                                inverted={true}
                                rounded={true}
                                onClick={(event) => this.onSubmit(event)}
                              >
                                Next Step
                            </Button>
                          </PanelFooter>
    
                          </div>
    
    
                        );
    
        }//End switch
    
        //end render
      }
    
    }
    
    export default AddConditionDashboard;
    

    这是我的子组件 - 在这里我需要动态添加新的`字段,其值需要传输到父组件。

        class AddConditionCURLPath extends React.Component {
    
      render() {
        const {error} = this.props;
    
        return (
          <div>
    
            <Panel theme="info">
    
            {error ? <Message inverted={true}  rounded={true}  theme="error">{error}</Message>  : null}
            <Container>
              Configure URL Path - What Pages A Visitor Needs to Visit to meet this conditino
                <Divider />
    
                <Input
                  value={this.props.urlPath}
                  label=""
                  type="text"
                  buttonLabel="Add Condition"
                  name="add_segment"
                  onChange={this.props.onUserInputChange}
                  placeholder="Condition Title"
                />
    
                <Input
                  value={this.props.urlPath}
                  label=""
                  type="text"
                  buttonLabel="Add Condition"
                  name="add_segment"
                  onChange={this.props.onUserInputChange}
                  placeholder="Condition Title"
                />
    
                <Button
                    backgroundColor="primary"
                    color="white"
                    inverted={true}
                    rounded={true}
                    onClick={(event) => this.addInputField(event)}
                  >
                    Add Another Input Field
                </Button>
    
    
              </Container>
    
            </Panel>
    
          </div>
        );
      }
    
    }
    
    export default AddConditionCURLPath;
    

1 个答案:

答案 0 :(得分:4)

嗯,在处理动态输入的Component中,你可以有一个n输入的循环来显示,可以通过addInputField()递增。此数字可以存储在此组件的本地状态中,这可以是开头的简单实现

修改

parent:保存值和添加/提交方法,带值摘要

class Parent extends Component {
  state = {
    inputValues: ['default value 1', 'default value 2']
  }

  addInputField = () => {
    this.setState({
      inputValues: [...this.state.inputValues, '']
    })
  }

  onUserInputChange = (e, i) => {
    let inputValues = [...this.state.inputValues]

    inputValues[i] = e.target.value

    this.setState({
      inputValues
    })
  }

  onSubmit = (e) => {
    e.preventDefault()
    console.log(this.state.inputValues)
  }

  render() {
    const { inputValues } = this.state

    return (
        <form>
          <DynamicInputs inputValues={inputValues}
                         onUserInputChange={this.onUserInputChange}/>
          <button type="button" onClick={this.addInputField}>add</button>
          <ul>
            {inputValues.map((value, i) => (
                <li key={i}>{value}</li>
            ))}
          </ul>
          <button type="submit" onClick={this.onSubmit}>submit</button>
        </form>
    )
  }

}

child:输入的无状态组件

const DynamicInputs = ({ inputValues, onUserInputChange }) => {
  const inputs = inputValues.map((value, i) => (
      <input key={i}
             type="text"
             defaultValue={value}
             onChange={e => onUserInputChange(e, i)}/>
  ))
  return (
      <div>
        {inputs}
      </div>
  )
}