I encountered an issue recently with checkboxes in a React JS form. Apparently, there is a slight difference in what event handlers you should use. When it comes to creating a new row of data you must use an onChange
event handler and when updating a row of data, you use the onClick
event handler.
Why? Well, if you use the onChange
event handler on the update the state isn't maintained. I see this when I coded a component and the checkbox was originally checked (active) but when unchecked (inactive) and updated on the server, the database row still had the status of being active.
On closer inspection I had to check the checkbox twice before the actual state changed (from being active to unactive).
I'm currently learning the ins and outs of React JS and this behaviour was unexpected. Out of frustration I swapped out the event handler on the update row component to the onClick
one and the behaviour returned to how it should be: unchecking the checkbox (being active) resulted in the row of data in the database being inactive.
// ...
const changeValue = (field, val) => {
const newData = { ...data };
newData[field] = val;
setData(newData);
};
const changeActive = () => {
const newData = { ...data };
newData["active"] = !data.active;
setData(newData);
};
// ...
return (
<>
<h5 className="card-title">Categories :: New Category</h5>
<div>
<Link className="btn btn-outline-dark btn-md w-25" role="button" to="/dashboard/categories">Go Back</Link>
</div>
<hr />
<div className="container">
<div className="row">
<div className="col-lg-8">
<form onSubmit={validateSubmit}>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
id="name"
type="text"
name="name"
value={data.name ?? ""}
className="form-control form-control-lg"
placeholder="Enter a new category name"
onChange={(e) => changeValue("name", e.target.value)}
/>
</div>
<div className="form-group form-check">
<input
className="form-check-input"
type="checkbox"
value=""
id="active"
checked={data.active}
onChange={(e) => changeActive()}
/>
<label htmlFor="active">Active, yes or no?</label>
</div>
<button className="btn btn-outline-dark w-25" type="submit">Go</button>
</form>
</div>
<div className="col-lg-4">
</div>
</div>
</div>
<hr />
</>
);
That's the component above to create a row of data and the update is below.
const changeValue = (field, val) => {
const newData = { ...data };
newData[field] = val;
setData(newData);
};
const changeActive = () => {
const newData = { ...data };
newData["active"] = !data.active;
setData(newData);
};
// ...
return (
<>
<h5 className="card-title">Dashboard :: Edit Category</h5>
<div className="d-flex justify-content-start">
<Link className="btn btn-outline-dark btn-md w-25" to="/dashboard/categories">Go Back</Link>
</div>
<hr />
<div className="container">
<div className="row">
<div className="col-lg-8">
<form onSubmit={validateSubmit}>
<div className="form-group">
<label htmlFor="name">Name</label>
<input
id="name"
type="text"
name="name"
value={data.name ?? ""}
className="form-control form-control-lg"
placeholder="Enter a new category name"
onChange={(e) => changeValue("name", e.target.value)}
/>
</div>
<div className="form-group form-check">
<input
className="form-check-input"
type="checkbox"
value=""
id="active"
defaultChecked={data.active}
onClick={(e) => changeActive()}
/>
<label htmlFor="active">Active, yes or no?</label>
</div>
<button className="btn btn-outline-dark w-25" type="submit">Go</button>
</form>
</div>
<div className="col-lg-4">
</div>
</div>
</div>
<hr />
</>
);
After a few hours head scratching things are back to normal. From now on I'll know better to not use onChange
on the update part of a dashboard's CRUD. If you are starting out on the React JS learning journey hopefully this'll help you too.
Content on this site is licensed under a Creative Commons Attribution 4.0 International License. You are encouraged to link to, and share but with attribution.
Copyright ©2024 Leslie Quinn.