Search code examples
javascriptreactjssetstate

Mystery Parameter in setState, why does it work?


Going through a TypeScript + React course and building a todo list. My question is about a react feature though.

In the handler for adding a Todo, there is this function declared in setState

const App: React.FC= () => {

  const [todos, setTodos] = useState<Todo[]>([])

  const todoAddHandler = (text: string) => {
    // when its called.... where does the prevTodos state come from?
    setTodos(prevTodos => [...prevTodos, 
      {id: Math.random().toString(), text: text}])
  }

  return (
    <div className="App">
      <NewTodo onAddTodo={todoAddHandler}/>
      <TodoList items={todos}></TodoList>
    </div>
  );
}

export default App;

When the function is called in setState, it automatically calls the current state with it. Is this just a feature of setState? That if you declare a function within it the parameter will always be the current state when the function is called?

Was very confused when this parameter just... worked. :#


Solution

  • TL;DR Is this just a feature of setState? - Yes

    useState is a new way to use the exact same capabilities that this.state provides in a class

    Meaning that its core still relies on old this.setState({}) functionality. If you remember using this.setState(), you will know that it has a callback function available, which can be used like this:

    this.setState((currentState) => { /* do something with current state */ })
    

    This has now been transfered to useState hook's second destructured item [item, setItem] setItem, thus it has the same capability:

    setItem((currentState) => { /* do something with current state */ })

    You can read more about it here