Я действительно думаю, что лучшее, что вы пытаетесь сделать, - это сначала контролировать каждый отдельный вход.Сохраняйте эти значения в состоянии и просто работайте с событием onSubmit из формы.React даже рекомендовал этот подход здесь https://reactjs.org/docs/uncontrolled-components.html
В большинстве случаев мы рекомендуем использовать контролируемые компоненты для реализации форм.В контролируемом компоненте данные формы обрабатываются компонентом React.Альтернативой являются неконтролируемые компоненты, где данные формы обрабатываются самим DOM.
Вы можете прочитать об контролируемых здесь https://reactjs.org/docs/forms.html#controlled-components
Если вы хотите увидеть, как я сделалс простым контролем это будет выглядеть так https://codesandbox.io/s/2w9qnk8lxp Вы можете увидеть, если вы нажмете ввести событие отправки формы со значением keep в состоянии.
class CustomSelect extends React.Component {
items = [
{ id: 1, text: "Kappa 1" },
{ id: 2, text: "Kappa 2" },
{ id: 3, text: "Kappa 3" }
];
render() {
return (
<div className="custom-select">
<div>
Selected: {this.props.selected ? this.props.selected.text : "nothing"}
</div>
{this.items.map(item => {
return (
<button
key={item.id}
type="button"
onClick={() => this.props.onChange(item)}
>
{item.text}
</button>
);
})}
</div>
);
}
}
class Form extends React.Component {
state = {
firstInput: "",
selected: null
};
handleSubmit = event => {
event.preventDefault();
console.log("Form submit", this.state);
};
handleInputChange = name => event => {
this.setState({ [name]: event.target.value });
};
handleSelectedChanged = selected => {
this.setState({ selected });
};
render() {
console.log(this.state);
return (
<form onSubmit={this.handleSubmit}>
<label>This input will trigger form's onChange event</label>
<input
value={this.state.firstInput}
onChange={this.handleInputChange("firstInput")}
/>
<CustomSelect
name="kappa"
selected={this.state.selected}
onChange={this.handleSelectedChanged}
/>
</form>
);
}
}
Но если вы действительно хотите, чтобы ваш путьВы должны передать функцию handleChange в качестве обратного вызова дочерним элементам и использовать этот реквизит в качестве функции при нажатии на элемент.Пример здесь https://codesandbox.io/s/0o8545mn1p.
class CustomSelect extends React.Component {
items = [
{ id: 1, text: "Kappa 1" },
{ id: 2, text: "Kappa 2" },
{ id: 3, text: "Kappa 3" }
];
state = {
selected: null
};
handleSelect = item => {
this.setState({ selected: item });
this.props.onChange({ selected: item });
};
render() {
var { selected } = this.state;
return (
<div className="custom-select">
<input
name={this.props.name}
required
style={{ display: "none" }} // or type="hidden", whatever
value={selected ? selected.id : ""}
onChange={() => {}}
/>
<div>Selected: {selected ? selected.text : "nothing"}</div>
{this.items.map(item => {
return (
<button
key={item.id}
type="button"
onClick={() => this.handleSelect(item)}
>
{item.text}
</button>
);
})}
</div>
);
}
}
class Form extends React.Component {
handleChange = event => {
console.log("Form onChange");
};
render() {
return (
<form onChange={this.handleChange}>
<label>This input will trigger form's onChange event</label>
<input />
<CustomSelect name="kappa" onChange={this.handleChange} />
</form>
);
}
}