4

I was wondering if there is any difference between passing a value and passing a function to update state in a functional component when referencing a previous state, as in below:

import React, { useState } from "react";

export default function App() {
  const [counter, setCounter] = useState(0);
  const [counter2, setCounter2] = useState(0);

  const increaseCounter = () => {
    setCounter(counter + 1);
  };

  const increaseCounter2 = () => {
    setCounter2(prevState => prevState + 1);
  };

  return (
    <div className="App">
      <h1>Counter: {counter}</h1>
      <button type="button" onClick={increaseCounter}>
        Increase
      </button>
      <h1>Another Counter: {counter2}</h1>
      <button type="button" onClick={increaseCounter2}>
        Increase
      </button>
    </div>
  );
}

The official documentation mentions this in the functional updates section: https://reactjs.org/docs/hooks-reference.html#functional-updates

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

Yet here, it uses a different method: https://reactjs.org/docs/hooks-state.html

import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

I'd presume that it does not matter which way in a very basic example as above but there'll probably be cases where one is necessary/preferable to the other.

EDIT: just to clarify my only question is about the difference (when to use) between:

setCounter2(prevState => prevState + 1);

and

setCounter(count + 1);

I understand that in both cases in a real example, it (ie. setCounter) should ideally be taken to a separate function (not coded inline in jsx).

Wasteland
  • 4,889
  • 14
  • 45
  • 91

1 Answers1

5

UPDATE:

setCounter2(prevState => prevState + 1); and

setCounter(count + 1);

there is a differences but depending on use case. The way you have used in example there is no difference. But

// Example 1
useEffect(() => {
  setCounter(count + 1)
}, [count])

// Example 2
useEffect(() => {
  setCounter2(prevState => prevState + 1)
}, [])

in example 1: useEffect has a dependency requirement which is count. in example 2: useEffect dont have any dependency requirement reason prevState is a call back.

when to apply

  1. If useEffect only depends on count change then example 1 should apply
  2. if useEffect has other dependencies but you dont want to trigger useEffect on count change then example 2 should apply

useEffect(() => {
  if(someOtherThingsChanged) {
    setCounter2(prevState => prevState + 1)
  }
  
}, [someOtherThingsChanged])

You can read more in here

Monzoor Tamal
  • 790
  • 5
  • 15