Home > Blockchain >  react setstate change object inside array of object of array
react setstate change object inside array of object of array

Time:07-16

i have a problem with react i need to setstate a spesific user when i click at button "succeed" it will change the object inside to false this is the deatils first i have an array of object (users) and object that called "workoutDeatils" inside this object i have 3 object the last one on index 2 is called "workout" inside this workout i have a object of all the workout and i need to change it spesific the problem when i want to use the setstate of users on the change it dosent work (because it gets confused) what i need to do is: change status to false this one i know but how i will setstate the users with the map? it should be nasted loop?

import HomePage from "./componente/HomePage";
import React, { useState } from "react";
import WorkoutDeatilsField from "./componente/WorkoutDeatilsField";
import SpesificUser from "./componente/SpesificUser";
import Workout from "./componente/Workout";
import { BrowserRouter, Route, Routes } from "react-router-dom";
function App() {
  const [users, setUsers] = useState([]);
  const [spesificUserId, setSpesificUserId] = useState(0);
  const [spesificWorkOut, setSpesificWorkout] = useState();
  const spesificUser = users.find((user) => {
    return user.id == spesificUserId;
  });
  const getWorkoutDeatils = () => {
    const { workout } = spesificUser.workoutDeatils[2];
    const spesificWorkoutPlane = workout.find((workout) => {
      return workout.workoutNum == spesificWorkOut;
    });
    return spesificWorkoutPlane;
  };

  const findUserExists = (id) => {
    const checkUserExists = users.filter((user) => {
      return user.id == id;
    });

    return checkUserExists.length !== 0 ? true : false;
  };

  const addUser = (id, fullName, gender) => {
    const user = {
      id: id,
      fullName: fullName,
      gender: gender,
    };

    setUsers((prev) => {
      return [...prev, user];
    });
  };
  const setTraning = (trainWeek, trainInYears) => {
    const workoutInWeeks = new Array(Number(trainWeek)).fill(1);
    let kmcacluator = (trainInYears * 5) / trainWeek;

    const workoutDeatils = [
      {
        trainWeek: Number(trainWeek),
      },
      { trainYears: Number(trainInYears) },
      {
        workout: workoutInWeeks.map((workout, index) => {
          kmcacluator = kmcacluator   (kmcacluator / 100) * 15;
          return { workoutNum: index   1, km: Math.ceil(kmcacluator), status: true };
        }),
      },
    ];

    const afterMap = users.map((user) => {
      return user.id == spesificUserId ? { ...user, workoutDeatils } : { ...user };
    });
    setUsers(afterMap);
  };
const get = ()=>{
  const afterMap = users.map((user)=>{
  })
}
  return (
    <div className="App">
      <BrowserRouter>
        <Routes>
          <Route
            path="/"
            element={
              <HomePage findUserExists={findUserExists} addUser={addUser} setSpesificUserId={setSpesificUserId} />
            }
          ></Route>
          <Route
            path="/workoutdeatilsfield"
            element={<WorkoutDeatilsField spesificUser={spesificUser} setTraning={setTraning} />}
          ></Route>
          <Route
            path="/traning/:id"
            element={<SpesificUser setSpesificWorkout={setSpesificWorkout} spesificUser={spesificUser} />}
          ></Route>
          <Route path="/workout" element={<Workout getWorkoutDeatils={getWorkoutDeatils} />}></Route>
        </Routes>
      </BrowserRouter>

      <button
        onClick={() => {
          console.log(users);
        }}
      >
        Click
      </button>
    </div>
  );
}

export default App;



{
    "id": "1",
    "fullName": "dsa",
    "gender": "male",
    "workoutDeatils": [
        {
            "trainWeek": 3
        },
        {
            "trainYears": 2
        },
        {
            "workout": [
                {
                    "workoutNum": 1,
                    "km": 4,
                    "status": true
                },
                {
                    "workoutNum": 2,
                    "km": 5,
                    "status": true
                },
                {
                    "workoutNum": 3,
                    "km": 6,
                    "status": true
                }
            ]
        }
    ]
}

this is an example how it add user with his deatils

CodePudding user response:

React's setState doesn't re-render the component if the state does not change. "state change" means you call setState with a value different from the previous one. "different" means it is not strictly equal (===) to the previous one. In JavaScript objects are compared by reference, so in order to change an object with setState you have to set a new object.

Thankfully, setState can receive a function that takes the previous states and computates the next one, particularlly useful for your use case when you want to update a nested property of an object. The key here is that you have to declare a new object and put all the data of the old object into the new one, changing only the value you want to change. With some spreading (...) and array methods (filter, find) you can easily, for example, toggle the status of the third wourkout.

    const workoutNum = 3 // Or whatever workout you want to change
    
    setUser(previous => {
      const workoutToChange = previous.workoutDetails[2].workout
        .find(d => d.workoutNum === workoutNum)
    
      return {
        ...previous,
        workoutDetails: [
          ...previous.workoutDetails.filter(details => !details.workout),
          { workout: [
            ...previous.workoutDetails[2].filter(w => w.workountNum  === workoutNum),
            { ...workoutToChange, status: !workoutToChange.status }
          ]}
        ]
      }
    })
  • Related