动态添加 React 组件

IT技术 javascript reactjs
2021-05-26 05:15:46

语境

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

问题

不知道如何去做:

  1. 无需限定状态(固定数量的urlpath1urlpath2在父组件等)。
  2. 无需<Input/>在子组件中定义固定数量的大子组件。

这是我的父组件 - 无论<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个回答

嗯,在处理动态输入的组件中,您可以有一个 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>
  )
}