Как сохранить выбор поля формы для радио и выбрать входы в динамически генерируемой форме реакции? - PullRequest
0 голосов
/ 08 апреля 2019

Мне не удается сохранить выбор полей формы из состояния при динамическом рендеринге наборов вопросов в форме многошагового мастера. Каждый раз, когда я выбираю Далее или Назад, пользовательский интерфейс полей формы сбрасывается, тогда как я вижу, что состояние установлено правильно.

Я попытался передать соответствующий реквизит из контейнера приложения в проверенный реквизит в компонентах RadioInput и SelectInput, однако это не работает так, как я этого ожидаю. Я попытался установить флажок, но я не слишком уверен, как динамически установить проверенное состояние, чтобы позже правильно его идентифицировать. Я перебрал ряд онлайн-поисков, но придумал совсем немного - есть идеи?

import React, { Component } from "react";
import "./App.css";
import RadioInput from "./components/RadioInput";
import SelectInput from "./components/SelectInput";

//SAMPLE DATA

const data = [
  {
    step: 1,
    title: "Example Step",
    stepID: 0,
    questions: [
      {
        title: "What is your favorite color?",
        name: "favColor",
        info: "",
        input_type: "select",
        required: true,
        values: [
          {
            label: "Green",
            value: "green",
            optionsID: 0
          },
          {
            label: "Red",
            value: "red",
            optionsID: 1
          },
          {
            label: "Blue",
            value: "blue",
            optionsID: 2
          }
        ],
        objectID: 1
      },
      {
        title: "Do you consider yourself healthy?",
        info: "",
        input_type: "radio",
        required: true,
        values: [
          {
            name: "health",
            label: "No",
            value: false,
            optionsID: 0
          },
          {
            name: "health",
            label: "Yes",
            value: true,
            optionsID: 1
          }
        ],
        objectID: 2
      },
    ]
  }
];



function hasValue(obj, key, value) {
  return obj.hasOwnProperty(key) && obj[key] === value;
}

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      step: 1,
      data
    };

    this.handleRadioChange = this.handleChange.bind(this);
    this._next = this._next.bind(this)
    this._prev = this._prev.bind(this)
  }

  handleChange = input => e => {
    console.log("checked - " + e.target.checked)
    this.setState({
      [input]: e.target.value,
    });
  };

  //NAVIGATION
  _next() {
    let step = this.state.step;
    step = step >= 2? 3: step + 1
    this.setState({
      step
    }) 
  }
  _prev() {
    let step = this.state.step
    step = step <= 1? 1: step - 1
    this.setState({
      step
    })
  }
  get nextButton() {
    let step = this.state.step;
    if(step < data.length) {
      return (
        <button className="btn" type="button" onClick={this._next}>
        Next
        </button>
      )
    }
    return null;
  }
  get backButton(){
  let step = this.state.step;
  if(step !== 1){
    return (
      <button 
        className="btn btn-secondary" 
        type="button" onClick={this._prev}>
      Back
      </button>
    )
  }
  return null;
}

get submitButton() {
  let step = this.state.step;
  if (step === data.length) {
    return (
      <button
      className="btn"
      type="button"
      onClick={this.onSubmitHandler}>Check Results
      </button>
    )
  }
  return null;
}

  render() {
    return (
      <div className="App">
        <h1>TEST FORM</h1>
        {data.map(questionstep => {
          if (hasValue(questionstep, "step", this.state.step) === true) {
            return (
              <h2 key={questionstep.stepID}>
                Step {this.state.step} of {data.length} - {questionstep.title}
              </h2>
            );
          }
          return null;
        })}

        <form>
          {data.map(questionstep => (
            questionstep.questions.map(q => {
            if (hasValue(questionstep, "step", this.state.step) === true)  
            if (q.input_type === "radio") {
              return (
                ```<RadioInput
                  key={q.objectID}
                  id={q.objectID}
                  title={q.title}
                  values={q.values}
                  onChange={this.handleChange}
                ```/>
              );
            } else {
              return (
                ```<SelectInput
                  key={q.objectID}
                  id={q.objectID}
                  title={q.title}
                  name={q.name}
                  values={q.values}
                  onChange={this.handleChange}
                ```/>
              );
            } 
            return null;
            })
          ))}
        </form>

          {this.backButton}
          {this.nextButton}
          {this.submitButton}
      </div>
    );
  }
}

export default App;


import React, { Component } from "react";

export class RadioInput extends Component {
  render() {
    const { values, onChange, title } = this.props
    return (
      <div className="form-field">
        <span>{title}</span>
        {values.map(val => (
          <label className="radio-label" key={val.optionsID}>

            <input
              className="radio-options"
              key={val.optionsID}
              type="radio"
              name={val.name}
              value={val.value}
              onChange={onChange(val.name)}
            />

            {val.label}
          </label>

        ))}
      </div>
    );
  }
}

export default RadioInput;


import React, { Component } from "react";

export class SelectInput extends Component {
  render() {
    const { title, id, name, onChange, values } = this.props;
    return (
      <div className="form-field">
        <span>{title}</span>

          <select 
            className="select-options"
            key={id} 
            name={name}
            onChange={onChange(name)}>
              {values.map(val => (

                <React.Fragment key={val.optionsID}>
                  <option value="" hidden>Select an option</option>
                  <option  
                  value={val.value}
                  key={val.optionsID}
                  >
                    {val.label}
                  </option>
                  </React.Fragment>
        ))}

          </select>
      </div>
    );
  }
}

export default SelectInput;

Я ожидаю, что при прохождении и заполнении формы при переходе назад и вперед по многоэтапному мастеру путем выбора кнопок «назад» / «далее» ранее выбранные поля будут отображаться в пользовательском интерфейсе. На данный момент форма сбрасывает интерфейс каждый раз, когда я выбираю следующий или обратно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...