Home > Enterprise >  How can I update an array within an object in react useState Hook
How can I update an array within an object in react useState Hook

Time:01-31

I am trying to create a nested dynamic form in React. My goal is to be able to add days to the form dynamically as well as exercises inside the day.

Here is what my state looks like:

const [formFields, setFormFields] = React.useState({
    name: '',
    price: '',
    duration: '',
    description: '',
    daysPerWeek: '',
    allExercises: [
      {
        day: 'Monday',
        exercises: [
          {
            name: '',
            sets: '',
            reps: '',
            link: '',
          },
        ],
      },
    ],
  });

I am able to add a new day with this method

function addDay() {
    const newDay = {
      day: '',
      exercises: [
        {
          name: '',
          sets: '',
          reps: '',
          link: '',
        },
      ],
    };
    setFormFields((prev) => ({
      ...prev,
      allExercises: [...prev.allExercises, newDay],
    }));
  }

But I want to have a button that will populate only the exercises array inside a specific day.

CodePudding user response:

You should be able to do something like this:

setFormFields((prev) => ({
  ...prev,
  allExercises: prev.allExercises.map(x => {
    if (x.day !== 'Tuesday') {
      return x;
    }
    return {...x, exercises: [...x.exercises, ...newExercisesForTuesday]};
  }),
}));

You may want to consider using useReducer if things get more complex than this though.

CodePudding user response:

i provide a sample code here you must pass a specific day to a func , loop for specific day and change it

[https://codesandbox.io/s/determined-frog-w6dr3l?file=/src/App.js][1]

CodePudding user response:

You should try to do something like this:

// Get a hook function
const {
  useState
} = React;

const Example = ({
  title
}) => {
  const [formFields, setFormFields] = React.useState({
    name: '',
    price: '',
    duration: '',
    description: '',
    daysPerWeek: '',
    allExercises: [{
      day: 'Monday',
      exercises: [],
    }, ],
  });

  function addDay() {
    const newExercises = {
      name: 'pushup',
      sets: '12',
      reps: '1',
      link: '',
    };

    const StateCopy = { ...formFields
    }



    const exercises = StateCopy.allExercises.map(item => {
      if (item.day === "Monday") {
        item.exercises.push(newExercises)
      }
      return item
    });
    StateCopy.allExercises = exercises;

    setFormFields({ ...StateCopy
    })
  }

  console.log(formFields)

  return ( <
    div >
    <
    button onClick = {
      addDay
    } >
    Click me <
    /button> < /
    div >
  );
};

// Render it
ReactDOM.createRoot(
  document.getElementById("root")
).render( <
  Example title = "Example using Hooks:" / >
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>

CodePudding user response:

You can use the spread operator syntex to create copy of deeply nested object properties, and then update the specific one, but this might get ugly as your code grows.

Alternatively, you can use Immer Library to update deeply nested properties.

  • Related