Home > Back-end >  How to increment inside .map() in react
How to increment inside .map() in react

Time:10-20

I would like to increment salary number inside map function. enter image description here

My code is currently working but I would like to know is this a correct way to increment number in React or what is the better method or how else should I do it?

find below the code so far

const users = [
  {
    id: 1,
    name: "Tiger Nixon",
    salary: 320800,
    age: 61,
  },
  {
    id: 2,
    name: "Garrett Winters",
    salary: 170750,
    age: 63,
  },
  {
    id: 3,
    name: "Ashton Cox",
    salary: 86000,
    age: 66,
  },
  {
    id: 4,
    name: "Cedric Kelly",
    salary: 433060,
    age: 22,
  }
]
const [salary, setSalary] = useState(users)

const incrementSalary = (employeeSalary) => {
  salary.map(x => 
    x.salary === employeeSalary? {...salary, salary : x.salary  = 1} : x 
  )
  setSalary([...salary])
}

return (
  <tbody>
    {salary.map((employee) => (
      <tr key={employee.id}>
        <th>{employee.id}</th>
        <td>{employee.name}</td>
        <td>{employee.age}</td>
        <td>
          <button>
            -
          </button>
          <span>{employee.salary}</span>
          <button onClick={() => incrementSalary(employee.salary)}>
             
          </button>
        </td>
      </tr>
    )}
  </tbody>

CodePudding user response:

No, doing x.salary = 1 mutates the existing state.

The correct way is to apply the immutable update patten: shallow copy all state, and nested state, that is being updated. You should also use a functional state update to correctly update from the previous state instead of whatever the current state value is that is closed over in callback scope.

You will also want to use an id or some other GUID to uniquely identify the employee element object you want to increment the salary property of.

Example:

const incrementSalary = (employeeId) => {
  setSalary(salary => salary.map(employee => 
    employee.id === employeeId
      ? {
        ...salary,
        salary: employee.salary   1
      }
      : x 
  ));
};

...

{salary.map((employee) => (
  <tr key={employee.id}>
    <th>{employee.id}</th>
    <td>{employee.name}</td>
    <td>{employee.age}</td>
    <td>
      <button>-</button>
      <span>{employee.salary}</span>
      <button onClick={() => incrementSalary(employee.id)}>
         
      </button>
    </td>
  </tr>
)}

CodePudding user response:

It's silly to map over the whole array to increment one number. map takes a second parameter - the index of the array.

This is the 'proper' way with immutability.

const defaultUsers = [
  {
    id: 1,
    name: 'Tiger Nixon',
    salary: 320800,
    age: 61,
  },
  {
    id: 2,
    name: 'Garrett Winters',
    salary: 170750,
    age: 63,
  },
  {
    id: 3,
    name: 'Ashton Cox',
    salary: 86000,
    age: 66,
  },
  {
    id: 4,
    name: 'Cedric Kelly',
    salary: 433060,
    age: 22,
  },
];

export default function App() {
  const [users, setUsers] = useState(defaultUsers);

  const incrementSalary = (index) => {
    setUsers((prevUsers) => {
      const newUsers = [...prevUsers];
      newUsers[index] = {
        ...newUsers[index],
        salary: newUsers[index].salary   1,
      };
      return newUsers;
    });
  };

  return (
    <tbody>
      {users.map((employee, index) => (
        <tr key={employee.id}>
          <th>{employee.id}</th>
          <td>{employee.name}</td>
          <td>{employee.age}</td>
          <td>
            <button>-</button>
            <span>{employee.salary}</span>
            <button onClick={() => incrementSalary(index)}> </button>
          </td>
        </tr>
      ))}
    </tbody>
  );
}

Stackblitz: https://stackblitz.com/edit/react-ts-a9rsnm?file=App.tsx


This is the faster way that gets you flamed by other React devs.

const defaultUsers = [
  {
    id: 1,
    name: 'Tiger Nixon',
    salary: 320800,
    age: 61,
  },
  {
    id: 2,
    name: 'Garrett Winters',
    salary: 170750,
    age: 63,
  },
  {
    id: 3,
    name: 'Ashton Cox',
    salary: 86000,
    age: 66,
  },
  {
    id: 4,
    name: 'Cedric Kelly',
    salary: 433060,
    age: 22,
  },
];

export default function App() {
  const users = useRef(defaultUsers).current;
  const [_, forceUpdate] = useReducer((x) => x   1, 0);

  const incrementSalary = (index) => {
    users[index].salary  ;
    forceUpdate();
  };

  return (
    <tbody>
      {users.map((employee, index) => (
        <tr key={employee.id}>
          <th>{employee.id}</th>
          <td>{employee.name}</td>
          <td>{employee.age}</td>
          <td>
            <button>-</button>
            <span>{employee.salary}</span>
            <button onClick={() => incrementSalary(index)}> </button>
          </td>
        </tr>
      ))}
    </tbody>
  );
}

Stackblitz: https://stackblitz.com/edit/react-ts-f3rvaa?file=App.tsx

  • Related