I'm working on a form in which one of the input items will be a select list. I am trying to implement the form by using reusable components. The hierarchy is this:
<SignupForm>
<CountrySelectList>
<SelectList>
I am able to get the select list to render, but I am not sure how to pass the needed props
to the child componets in order to bind the selection from the drop down list? Here are the components (with some form fields removed for brevity).
SignupForm
class SignupForm extends React.Component {
constructor(props) {
super(props);
this.state = {
country: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
event.preventDefault();
let formData = new FormData();
formData.append("Country", this.state.country);;
fetch("api/account/signup", {
method: "POST",
body: formData })
.then(response => response.json())
.then(data => console.log(data));
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<CountrySelectList name="country" value={this.state.country} onChange={this.handleChange} />
<SubmitButton btnText="Submit"/>
</form>
);
}
}
export default SignupForm;
CountrySelectList
class CountrySelectList extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
data: []
};
}
async componentDidMount() {
try {
const response = await fetch('api/location/countries');
const json = await response.json();
this.setState({
data: json,
isLoaded: true
});
} catch (error) {
console.log(error);
}
}
render() {
const { error, isLoaded, data } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <LoadingSpinner/>;
} else {
return (
<SelectListGroup>
<Label label="country" title="Country"/>
<SelectList data={data} value={this.props.value} onChange={this.props.onChange} />
</SelectListGroup>
);
}
}
}
export default CountrySelectList;
SelectList
export default function SelectList({ data, value, onChange, addClass="" }) {
return (
<select
value={value}
className={`form-select ${addClass}`}
onChange={onChange}>
{data.map((data, index) => (
<option key={index} value={data.value}>
{data.text}
</option>
))}
</select>
);
}