I wrote the below code which displays each item with {t.title}
When I click on each checkbox item, plant_id: t.plant_id
is correctly stored in setPlantsFill
But when I try to enter input value, for example, the third value of data[index]["effectiveness"] = e.target.value;
, an error is shown to me: Uncaught TypeError: data[index] is undefined
But if I enter in order, there is no problem
How can I solve this problem?
I want the final output for each item to be as (for example we have 3 item in allPlants):
{ "plant_id": 2, "effectiveness": 100 }, { "plant_id": 24, "effectiveness": 80 }, { "plant_id": 13, "effectiveness": 15 }
this is my code:
const [allPlants, setAllPlants] = useState([]);
const [plantsFill, setPlantsFill] = useState([]);
{allPlants.map((t, index) => {
return (
<div className="form-row mb-2" key={index}>
<div className="col-md-2">
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
onChange={(e) => {
if (e.target.checked) {
setPlantsFill([
...plantsFill,
{
plant_id: t.plant_id,
},
]);
} else {
// remove from list
setPlantsFill(
plantsFill.filter(
(pItem) => pItem.plant_id !== t.plant_id
)
);
}
}}
value={plantsFill}
/>
<label className="form-check-label">{t.title}</label>
</div>
</div>
<div className="col-md-1">
<input
type="text"
className="form-control"
onChange={(e) => {
let data = [...plantsFill];
data[index]["effectiveness"] = e.target.value;
setPlantsFill(data);
}}
/>
</div>
</div>
);
})}
CodePudding user response:
With the discussion I tried something and it works as I understand the problem :
const onCheckChange = (e, t) => {
if (e.target.checked) {
setPlantsFill([
...plantsFill,
{
plant_id: t.plant_id
}
]);
} else {
// remove from list
setPlantsFill(
plantsFill.filter((pItem) => pItem.plant_id !== t.plant_id)
);
}
};
const onTextChange = (e, t) => {
let data = [...plantsFill];
const index = data.findIndex((d) => d.plant_id === t.plant_id);
if (index > -1) {
data[index].effectiveness = e.target.value;
}
setPlantsFill(data);
};
return (
<div>
{allPlants.map((t, index) => {
return (
<div className="form-row mb-2" key={index}>
<div className="col-md-2">
<div className="form-check">
<input
type="checkbox"
className="form-check-input"
onChange={(e) => onCheckChange(e, t)}
value={!!plantsFill.find((p) => p.plant_id === t.plant_id)}
/>
<label className="form-check-label">{t.title}</label>
</div>
</div>
<div className="col-md-1">
{!!plantsFill.find((p) => p.plant_id === t.plant_id) && (
<input
type="text"
className="form-control"
onChange={(e) => onTextChange(e, t)}
/>
)}
</div>
</div>
);
})}
</div>
);