Мне не удается сохранить выбор полей формы из состояния при динамическом рендеринге наборов вопросов в форме многошагового мастера. Каждый раз, когда я выбираю Далее или Назад, пользовательский интерфейс полей формы сбрасывается, тогда как я вижу, что состояние установлено правильно.
Я попытался передать соответствующий реквизит из контейнера приложения в проверенный реквизит в компонентах 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;
Я ожидаю, что при прохождении и заполнении формы при переходе назад и вперед по многоэтапному мастеру путем выбора кнопок «назад» / «далее» ранее выбранные поля будут отображаться в пользовательском интерфейсе. На данный момент форма сбрасывает интерфейс каждый раз, когда я выбираю следующий или обратно