Динамически создавать массив входов в React - PullRequest
0 голосов
/ 13 сентября 2018

Я все еще новичок в рамках React.Я работаю над проектом, в котором я хотел бы позволить пользователю создавать выбранные поля.В настоящее время я использую реагировать на выбор, чтобы отобразить выбранные поля или выпадающие списки.Мне нужны значения, которые они выбрали из полей ввода select.Проблема в том, что пользователь должен иметь возможность создавать несколько полей ввода.Каждое поле ввода должно иметь уникальный ключ.Я хочу иметь возможность получать значения по мере их выбора.

То, что я имею до сих пор:

 class OptionsComponent extends React.Component{
  constructor(props){
   super(props);
   this.state = {
    fields: [],
    parentArray: [],
    optionsArray: [],
    selectedOption:'',

   };

this.handleSelect = this.handleSelect.bind(this); 
}

 handleSelect = (event, index) => {
  console.log(event);
  console.log(optionsArray);
  console.log(selectedOption);
  const optionsArray = [...this.state.optionsArray];
  let selectedOption = event.label;
  optionsArray[index]= event.target.value;

  this.setState({
    optionsArray,
    selectedOption: event.label,
  })}

 render(){

return(

  <div className="">
    <div className="optionsArea">

      { this.state.parentArray.map((el, index) =>
        <div key={index} className="selectDropdown ">
            { this.state.optionsArray.map((el, index) => {
              return <Select
              key={index}
              name="optionsSelect"
              className="userOptionSelectDropdown"
              placeholder="Select Variable"
              value={this.state.selectedOption}
              onChange={(event) => this.handleSelect(event)}
              onSelect={(event) => this.handleSelect(event)}
              options={this.state.fields.map((field, index) => {
              return {value: index, label: field.name;
            })} />
          })}
        </div>
      )
    }
    </div>

  </div>

    );
   }
 }

Заранее прошу прощения, если это дубликат.Я проверил подобные вопросы и сделал поиск в Google, и я ничего не смог найти.Прямо сейчас, когда я использую этот код в своем компоненте, он ничего не рендерит.Я не совсем уверен, почему.Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Не уверен, что я точно понял, что вы просите / пытаетесь сделать, но я верю, что это сделает это:

  1. Intializes поле Select с параметрами
  2. Создает новыйВыберите поле с параметрами из пользовательского ввода
  3. В каждом поле хранится выбранная опция (если она была выбрана)
  4. При нажатии «Отправить форму» отображаются все выбранные параметры

Рабочий пример: https://codesandbox.io/s/81jlqp31p9

import each from "lodash/each";
import map from "lodash/map";
import isEmpty from "lodash/isEmpty";
import React, { Component, Fragment } from "react";
import Select from "react-select";

export default class DynamicSelect extends Component {
  state = {
    Fields: [
      {
        name: "Field0",
        options: [
          { value: "chocolate", label: "Chocolate" },
          { value: "strawberry", label: "Strawberry" },
          { value: "vanilla", label: "Vanilla" }
        ]
      }
    ],
    selectedOptions: {}
  };

  clearSelections = () => this.setState({ selectedOptions: [] });

  handleChange = (name, value) => {
    this.setState(prevState => ({
      selectedOptions: [
        ...this.state.selectedOptions,
        {
          name: value
        }
      ]
    }));
  };

  handleAddField = () => {
    this.setState(prevState => {
      const { newFields } = this.state;
      if (!newFields) return;
      const arr = newFields.split(",");
      const options = map(arr, val => ({ value: val, label: val }));

      return {
        newFields: "",
        Fields: [
          ...this.state.Fields,
          {
            name: `Field${this.state.Fields.length}`,
            options
          }
        ]
      };
    });
  };

  handleFieldChange = e => {
    this.setState({ newFields: e.target.value });
  };

  showSelectedOptions = selectedOptions => {
    return map(selectedOptions, ({ name }) => name + "");
  };

  handleSubmit = e => {
    e.preventDefault();

    const { selectedOptions } = this.state;

    alert(`Selection option(s): ${this.showSelectedOptions(selectedOptions)}`);
  };

  render() {
    const { Fields, newFields, selectedOptions } = this.state;

    return (
      <form onSubmit={this.handleSubmit} style={{ margin: 20 }}>
        <h3 style={{ textAlign: "center" }}>Dynamic Select Fields</h3>
        {!isEmpty(Fields) &&
          map(Fields, ({ name, options }, key) => (
            <div key={key} style={{ marginBottom: 20 }}>
              <div>{name}:</div>
              <Select
                name={name}
                value={selectedOptions[name]}
                onChange={({ value }) => this.handleChange(name, value)}
                options={options}
                style={{ marginBottom: 20 }}
              />
            </div>
          ))}
        <div style={{ marginTop: 20 }}>
          <input
            style={{ marginBottom: 5, width: "100%" }}
            type="text"
            className="uk-input"
            onChange={this.handleFieldChange}
            placeholder="Create a Select Field (option, option, option, ..etc)"
            value={newFields}
          />
          <br />
          <button
            onClick={this.handleAddField}
            className="uk-button uk-button-default"
            type="button"
            disabled={newFields ? false : true}
          >
            Add Field
          </button>
        </div>
        <div style={{ marginTop: 40 }}>
          <button
            className="uk-button uk-button-primary"
            type="submit"
            disabled={!isEmpty(selectedOptions) ? false : true}
          >
            Submit Form
          </button>
        </div>
      </form>
    );
  }
}
0 голосов
/ 14 сентября 2018

Вы можете установить имя компонента и получить его во время обработки handleSelect и получить значение напрямую (например, работает, если вы используете пользовательские элементы управления из начальной загрузки 4).Не забудьте использовать другое имя для индекса в опциях.

handleSelect = (event) => {
    let name = event.target.name;
    let value = event.target.value; 

    // perform action

    ...

}

, а затем при рендеринге создайте уникальное имя на карте, например, name={"optionsSelect_" + el + "_" + index} или как вам будет угодно:

...

{ this.state.parentArray.map((el, index) =>
    <div key={index} className="selectDropdown ">
        { this.state.optionsArray.map((el, index) => {
          return <Select
          key={index}
          name={"optionsSelect_" + el + "_" + index}
          className="userOptionSelectDropdown"
          placeholder="Select Variable"
          value={this.state.selectedOption}
          onChange={(event) => this.handleSelect(event)}
          onSelect={(event) => this.handleSelect(event)}
          options={this.state.fields.map((field, index2) => {
          return {value: index2, label: field.name;
        })} />
      })}
    </div>
  )
}

...

Если установка имени не работает, вы также можете попробовать ссылки:

...

{ this.state.parentArray.map((el, index) =>
    <div key={index} className="selectDropdown ">
        { this.state.optionsArray.map((el, index) => {
          return <Select
          key={index}
          ref={a => (this["optionsSelect_" + el + "_" + index] = a)}
          name={"optionsSelect_" + el + "_" + index}
          className="userOptionSelectDropdown"
          placeholder="Select Variable"
          value={this.state.selectedOption}
          onChange={(event) => this.handleSelect(event)}
          onSelect={(event) => this.handleSelect(event)}
          options={this.state.fields.map((field, index2) => {
          return {value: index2, label: field.name;
        })} />
      })}
    </div>
  )
}
...

, а затем получить его в свой дескриптор (вы получите полный компонент):

handleSelect = (event) => {
    let name = event.target.name;
    let element = this[name]; 

    // perform action

    ...

}

Существует множество способов получения выбранного значения с использованием чистого JavaScript, смотрите здесь .

Это очень важно!

если вам нужно изменить состояние на основе предыдущего состояния, не делайте этого:

    ...
    const optionsArray = [...this.state.optionsArray];
    let selectedOption = event.label;
    optionsArray[index]= event.target.value;

    this.setState({
        optionsArray,
        selectedOption: event.label,
    })
    ...

setState также получает функцию и выдаст вам предыдущее состояние для ее обработки,внесите любые необходимые изменения и ОБЕСПЕЧИТЕ , что они будут установлены правильно.

    ...    
    this.setState(prevState => {
        // get current state
        let newOptionsArray = prevState.optionsArray;
        let selectedOption = event.label; // or whatever
        newOptionsArray[index]= event.target.value; // or whatever

        return({
            optionsArray: newOptionsArray,
            selectedOption: event.label,
        });
    });
    ...

Прочтите в официальных документах , чтобы понять, как работает setState.

...