useState Lesson: Where is "prev" coming from?

In the state hook lesson, we end up with the following code at the end of the lesson:

import React, { useState } from "react";
import NewTask from "../Presentational/NewTask";
import TasksList from "../Presentational/TasksList";

export default function AppFunction() {
  const [newTask, setNewTask] = useState({});
  const [allTasks, setAllTasks] = useState([]);

  const handleChange = ({ target }) => {
    const { name, value } = target;
    setNewTask((prev) => ({ ...prev, id: Date.now(), [name]: value }));
  };

   const handleSubmit = (event) => {
    event.preventDefault();
    if (!newTask.title) return;
    setAllTasks((prev) => [newTask, ...prev]);
    setNewTask({});
    };

   const handleDelete = (taskIdToRemove) => {
    setAllTasks((prev) => prev.filter(
      (task) => task.id !== taskIdToRemove
    ));
  };
  


    return (
      <main>
        <h1>Tasks</h1>
        <NewTask
          newTask={newTask}
          handleChange={handleChange}
          handleSubmit={handleSubmit}
        />
        <TasksList allTasks={allTasks} handleDelete={handleDelete} />
      </main>
    );
}

In setNewTask and setAllTasks, where is the variable prev coming from? It is not defined anywhere in the code.

Hi @giga4397826988
Welcome to the forums!

The state hook provides a variable for the state and a function to update the state. From the react docs:

If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value.

You can name the parameter for the state in the callback function however you like. It does not have to be prev. But it will always receive the previous state.

Just like any other JavaScript function, you can name function parameters however you like without declaring them anywhere before.

Thanks for the response. Just to make sure I get it, prev (or foo or bar or whatever we call it) automatically receives the previous state for whatever “state” is associated with it? So in setNewTask prev is always the previous newTask? If that is the case why dont we just pass in the current/“previous” newTask and then have setNewTask update it?

If you pass a callback function to setNewTask, yes.

Consider the array method .map() for example. From the MDN docs:

map calls a provided callbackFn function once for each element in an array

const array = [1, 2, 3];
const double = (num) => num * 2;

console.log(array.map(double)); // [2, 4, 6]
console.log(array.map(item => item * 2)); // [2, 4, 6]

Whether you just pass an external callback function to the method call or you double each item inside the method, the callback will always be applied on each item of the array. The same principle applies for the state hook.

You don’t have to pass a callback function to the state setter. You can just pass a value to it and the state will be replaced by the new state. But sometimes you’d want to keep parts of the previous state. If the state is an array for example. And you just want to filter out one item of the array or add an item.