skip to Main Content

I have an array with this format:

[{exerciseName: 'Pec Deck', reps: 0, sets: 0},{exerciseName: 'Push-up', reps: 0, sets: 0}]

enter image description here

This array is stored initially here

const [currentWorkout,setCurrentWorkout] = useState(props.workout.exercises);

I want to change the array state with this inputs

enter image description here

This is the code of the inputs

const editExercises = currentWorkout.map((exercise,i)=>{
    return (<li key={i}><div className="exercisesContainer"><div><span className='exerciseName'>{exercise.exerciseName}</span></div><div className="repsSetsContainer"><span className='exerciseSets'> Sets - <input id={`sets${i}`}  onChange={handleChange} className="inputNumber" name="sets" type="number"/></span><span className='exerciseReps'> Reps - <input id={`reps${i}`}  onChange={handleChange} className="inputNumber" name="reps" type="number"/></span></div></div></li>)
})

function handleChange(event){
    const {name, value, id} = event.target
   
    setCurrentWorkout(prevFormData => {
        prevFormData.map((exercise,i)=>{
            return {
                ...exercise,
                [name]:value
            }
      })
      return exercise;
    })
}

How can i update the array state when clicking on the check button?

2

Answers


  1. You can use a map inside setCurrentWorkout to identify and update just an item matching your index i

    setCurrentWorkout(
        currentWorkout((item, index) => 
            index === i 
            ? {...item, sets : newSetCount, reps: newRepCount}
            : item 
    ))
    

    If you have access to the exercise name, you can also check item.exerciseName === exerciseName instead of the index. Just make sure that exerciseName is unique

    There are other techniques, such as updating currentWorkout directly, but then you are mutating the original source state directly which is not advised

    Login or Signup to reply.
  2. You could pass the index (or the exercise object itself) to handleChange to indicate which object to update.

    You also need to return the new array to be the next state from the updater function passed to setCurrentWorkout.

    onChange={e => handleChange(e, i)}
    
    function handleChange(event, i) {
        // ...
        setCurrentWorkout(prev => prev.map((exercise, j) => 
            j !== i ? exercise : {...exercise, [name]: value}));
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search