I have a function react component which has an object consisting of different values that renders in react form.
const initialInputValues = {
domain: '',
title1: '',
title2: '',
title3: '',
title4: '',
title5: '',
title6: '',
title7: '',
description1: '',
description2: '',
};
const [values, setValues] = useState(initialInputValues);
//handling input
const handleInputChange = (e) => {
const { name, value } = e.target;
setValues({...values, [name]: value });
}
//handle submit
const handleSubmit = (e) => {
e.preventDefault();
}
I have a reusable FormGroup component like this
<FormGroup
label='Domain'
name='domain'
type='url'
value={values.domain}
onChange={handleInputChange}
/>
<FormGroup
label='Title 1'
name='title1'
value={values.title1}
onChange={handleInputChange}
/>
<FormGroup
label='Title 2'
name='title2'
value={values.title2}
onChange={handleInputChange}
/>
<FormGroup
label='Title 2'
name='title2'
value={values.title2}
onChange={handleInputChange}
/>
<FormGroup
label='Title 3'
name='title3'
value={values.title3}
onChange={handleInputChange}
/>
I have a button under this FormGroup Title fields, now I want to append title4
, title5
, title6
, title7
one by one on click of this Add button.
<button
className='button__addField'
type='button'
onClick={handleAddTitle}
>
Add Title
</button>
Is there any other way except using useRef
and hide/show using CSS classes? I have tried that but looks like that is not a feasible solution if in future I want to expand title fields up to 12 or description fields up to 8 etc.
export default function App() {
const initialInputValues = {
domain: "",
title1: "",
title2: "",
title3: "",
title4: "",
title5: "",
title6: "",
title7: "",
description1: "",
description2: ""
};
const [values, setValues] = useState(initialInputValues);
const [titleNum, setTitleNum] = useState(3)
const handleInputChange = (e) => {
const { name, value } = e.target;
setValues({ ...values, [name]: value });
};
const handleSubmit = (e) => {
e.preventDefault();
};
return (
<div className="sidebar-area">
<form className="form-area" onSubmit={handleSubmit}>
<div className="form__buttons">
<button className="button__share" value="Share" type="submit">
Share
</button>
<button type="button" className="button__export">
Export
</button>
</div>
<div className="form__heading">
<div className="heading__iconTitle">
<h4 className="heading__title">Campaign Basics</h4>
</div>
</div>
<FormGroup
label="Domain"
name="domain"
type="url"
value={values.domain}
onChange={handleInputChange}
/>
{Array.from({length: titleNum}, (_,i, ind = i 1) => (
<FormGroup
label= {`Title ${ind}`}
name={`title${ind}`}
value={values[`title${ind}`] || ''}
onChange={handleInputChange}
/>
))}
<div className="form__addField">
<div>
<button
className="button__addField"
type="button"
onClick={() => setTitleNum(prev => prev 1)}
>
Add Title
</button>
</div>
</div>
<div className="form__group__inlineField">
<FormGroup
label="Path 1"
name="path1"
value={values.path1}
onChange={handleInputChange}
/>
<FormGroup
label="Path 2"
name="path2"
value={values.path2}
onChange={handleInputChange}
/>
</div>
<FormGroup
rows="2"
label="Description Line 1"
name="description1"
value={values.description1}
onChange={handleInputChange}
/>
<FormGroup
rows="2"
label="Description Line 2"
name="description2"
value={values.description2}
onChange={handleInputChange}
/>
</form>
</div>
);
}
CodePudding user response:
If you are effectively wanting a dynamic list of titles then I'd suggest storing an array of titles in the state and appending to this array when you want to add another title input. You will want to use
CodePudding user response:
it can be handle via dynamic state