I have a form in which I would like to render different fields based on a category which is selected from a dropdown. For instance in the following example, if there are categories named 'phones' and 'laptops, if 'laptops' is selected the form will include the field 'network' and if laptops' is selected, the form will include the field 'processor' (both are currently shown). What is the best way to go about doing this? I assume I would need to store the selected dropdown option in state and render the fields based on that, but I'm at a loss as to how to accomplish it without breaking what I currently have.
import React, { useState, useEffect } from "react";
import Layout from "../core/Layout";
import { isAuthenticated } from "../auth";
import { createProduct, getCategories } from './apiAdmin';
const AddProduct = () => {
const [values, setValues] = useState({
name: '', network: '', processor: '', categories: [], category: '', loading: false, error: '', createdProduct: '', redirectToProfile: false, formData: ''
});
const { user, token } = isAuthenticated();
const { name, network, processor, categories, category, loading, error, createdProduct, redirectToProfile, formData } = values;
const init = () => {
getCategories().then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
}
else {
setValues({...values, categories: data, formData: new FormData() });
}
});
};
useEffect(() => {
init();
}, []);
const handleChange = name => event => {
const value = event.target.value;
formData.set(name, value);
setValues({ ...values, [name]: value });
};
const clickSubmit = (event) => {
event.preventDefault();
setValues({ ...values, error: '', loading: true });
createProduct(user._id, token, formData)
.then(data => {
if (data.error) {
setValues({ ...values, error: data.error });
}
else {
setValues({ ...values, name: '', network: '', processor: '', loading: false, createdProduct: data.model });
}
});
};
const newPostForm = () => (
<form className='mb-3' onSubmit={clickSubmit} >
<div className='form-group'>
<label className='text-muted'>Category</label>
<select onChange={handleChange('category')} className='form-control'>
<option>Select a Category</option>
{ categories && categories.map((c, i) => (<option key={i} value={c._id}>{c.name}</option>)) }
</select>
</div>
<div className='form-group'>
<label className='text-muted'>Name</label>
<input
onChange={handleChange('name') }
type='text'
className='form-control'
value={name}
/>
</div>
// *****************************************************************************************
// ************ THIS SHOULD BE RENDERED ONLY IF CATEGORY 'PHONES' IS SELECTED ************
// *****************************************************************************************
<div className='form-group'>
<label className='text-muted'>Network</label>
<input
onChange={handleChange('network') }
type='text'
className='form-control'
value={network}
/>
</div>
// *****************************************************************************************
// *********** THIS SHOULD BE RENDERED ONLY IF CATEGORY 'LAPTOPS' IS SELECTED ************
// *****************************************************************************************
<div className='form-group'>
<label className='text-muted'>Processor</label>
<input
onChange={handleChange('processor') }
type='text'
className='form-control'
value={processor}
/>
</div>
<button className='btn btn-outline-primary'>
Submit
</button>
</form>
);
return (
<Layout title='Add Product' description={`Welcome, ${user.name}.`} >
<div className='row'>
<div className='col-md-8 offset-md-2'>
{newPostForm()}
</div>
</div>
</Layout>
)
}
export default AddProduct;
category@mxvx