i´m trying to handle the state of my input fields in react via my handleChange method. It works fine for my titles (exercise name) but not for the input fields below my titles (reps and weight)
export const Workout = () => {
const initalExercises = [
{
title: "Bench Press",
sets: [
{
reps: 1,
weight: 80,
},
{
reps: 2,
weight: 80,
},
],
},
{
title: "Squat",
sets: [
{
reps: 2,
weight: 90,
},
{
reps: 4,
weight: 90,
},
],
},
];
const [exercises, setExercises] = useState(initalExercises);
// //handles input change
const handleChangeTitle = (e, exercisesIndex) => {
const { value } = e.target;
const onChangeVal = [...exercises];
onChangeVal[exercisesIndex].title = value;
console.log(value);
setExercises(onChangeVal);
};
const handleChange = (e, exercisesIndex, setIndex) => {
const { name, value } = e.target;
const onChangeVal = [...exercises];
onChangeVal[exercisesIndex].sets[setIndex][name] = value;
setExercises(onChangeVal);
console.log(onChangeVal);
};
here is my jsx
return (
<div className="exercisesWrapper">
<div className="exercisesContainer">
{/* <button onClick={addExrc}>Add Exercise</button> */}
{
<button className="addExrc" onClick={addExercise}>
Add Exercise
</button>
}
{exercises.map((exercise, exercisesIndex) => (
<div key={exercisesIndex}>
<div>
<button
className="deleteExrc"
onClick={() => handleExerciseDelete(exercisesIndex)}
>
-
</button>
<input
className="inputField"
id="titleInput"
name="title"
type="text"
placeholder="Exercise"
value={exercise.title}
onChange={(e) => handleChangeTitle(e, exercisesIndex)}
/>
<button
className="addSet"
onClick={() => addCurrentSet(exercisesIndex)}
>
+ Add set
</button>
{exercise.sets.map((set, setIndex) => (
<div
key={`${exercise.title}-${setIndex}`}
className="currentSetInput"
>
<input
className="inputField"
name="weight"
type="text"
value={set.weight}
onChange={(e) => handleChange(e, setIndex)}
/>
<input
className="inputField"
name="reps"
type="text"
value={set.reps}
onChange={(e) => handleChange(e, setIndex)}
/>
<button
className="deleteSet"
onClick={() => handleDelete(exercisesIndex, setIndex)}
>
-
</button>
</div>
))}
</div>
</div>
))}
</div>
</div>
);
Every other function is working fine its just the handling of my weight and reps input thats not working
2
Answers
It looks like you just need to add the exercisesIndex as the 2nd argument when you call the handleChange function because the function is expecting 3 arguments (e, exercisesIndex, setIndex) and you are only providing 2 arguments (e, setIndex). Without providing the 3rd argument, the setIndex variable inside the handleChange function will be undefined which is causing that error.
onChange={(e) => handleChange(e, exercisesIndex, setIndex)}
Try using
exercise.map()
instead ofexercise.sets.map()
in your second iteration.Instead of this:
Try this: