Aashiq
Aashiq

Reputation: 497

Callback inside a useState updater function in react Hooks

Im new to hook and so is react,Ive been watching some tutorials lately,I saw Ben awad's video for dynamic forms and I tried replicating it.There he used a callback inside the useState updater function which seems new to me.He used link setPeople(currentPeople => {}) What is the argument currentPeople come from and why its used,Can you someone please explain,Thanks in advance!

import { useState } from "react";
import "./App.css";
import { generate } from "shortid";
interface Person {
  id: string;
  firstName: string;
  lastName: string;
}
function App() {
  const [people, setPeople] = useState<Person[]>([
    {
      id: "5",
      firstName: "Aashiq",
      lastName: "Ahmed",
    },
  ]);
  return (
    <>
      <h2 style={{ textAlign: "center" }}>Dynamic Form </h2>
      <div style={{ textAlign: "center" }}>
        <button
          onClick={() => {
            setPeople((currentPeople) => [
              ...currentPeople,
              {
                id: generate(),
                firstName: "",
                lastName: "",
              },
            ]);
          }}
        >
          add new person
        </button>
        {people.map((p, index) => {
          return (
            <div key={p.id}>
              <input
                placeholder="first name"
                value={p.firstName}
                onChange={(e) => {
                  const firstName = e.target.value;
                  setPeople((
                    currentPeople 
                  ) =>
                    currentPeople.map((x) =>
                      x.id === p.id ? { ...x, firstName } : x
                    )
                  );
                }}
              />
              <input
                placeholder="last name"
                value={p.lastName}
                onChange={(e) => {
                  const lastName = e.target.value;
                  setPeople((currentPeople) =>
                    currentPeople.map((x) =>
                      x.id === p.id ? { ...x,lastName } : x
                    )
                  );
                }}
              />
            <button onClick={()=> setPeople( currentPeople =>currentPeople.filter(x=> x.id !== p.id) )}>x</button>
            </div>
          );
        })}
        <div>
          
          <pre>{JSON.stringify(people,  null,  3)}</pre>
        
        </div>
      </div>
    </>
  );
}

export default App;

Upvotes: 1

Views: 501

Answers (2)

Anuja
Anuja

Reputation: 1038

It is the current value of that state, this might come in handy, when you want to use the previous state to calculate the next state. An example would be a toggle function, that would toggle a modal or sth.

const [isOpen, setIsOpen] = useState(false);
const toggleIsOpen = () => setIsOpen(open=>!open);

Upvotes: 1

Nemanja Lazarevic
Nemanja Lazarevic

Reputation: 1047

No better explanation than the official one. Here is the link: https://reactjs.org/docs/hooks-reference.html#usestate

setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

Your currentPeople is what the variable name suggests, the current value of the const [people, setPeople] = useState<Person[] For example: You might send only one person that you want to add to your people's array, so you end up just attaching that Person to an already existing array of Persons. Sure you could use setPeople([...people, newPerson]) but this wouldn't be correct in 100% of places because people might not have the latest value so the callback function comes to the rescue.

Upvotes: 1

Related Questions