I was debugging a React app and noticed that some of my functions were called multiple times in a way I could not explain.
I initially thought it was some sort of "developer feature" and tried to run a build, and all I could see if that the APIs that should not be called were called once instead of twice:
import { useCallback, useState } from "react";
function App() {
  const cities = ["montreal", "london", "shanghai"];
  const [city, setCity] = useState(cities[0]);
  const getCityParameter = useCallback(
    (newCity) => {
      console.log("[1] getCityParameter");
      console.log(`newCity: ${newCity}`);
      console.log(`city: ${city}`);
      return (newCity ?? city).toUpperCase();
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [city]
  );
  const [cityParameter, setCityParameter] = useState(getCityParameter());
  const handleChange = useCallback(
    (event) => {
      const newCity = event?.target.value;
      console.log("handleCityChange");
      console.log(`newCity: ${newCity}`);
      if (newCity !== undefined) {
        setCity(newCity);
      }
      const newCityParameter = getCityParameter(newCity);
      setCityParameter(newCityParameter);
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [city]
  );
  return (
    <>
      <select onChange={handleChange} value={city}>
        {cities.map((city) => {
          return (
            <option value={city} key={city}>
              {city}
            </option>
          );
        })}
      </select>
      <div>{cityParameter}</div>
    </>
  );
}
export default App;
I created this code sandbox here: https://codesandbox.io/s/restless-butterfly-brh7fk?file=/src/App.js
If you clear the console log, and change the dropdown, you will notice that getCityParameter is called 3 times when I would expect it to be called once.
This seems to be a pretty low-level React feature and I apologize for the "not-so-small" example - this is the best I could come up with to reproduce the behavior.
Can anyone explain?
 
    