reactjsuse-stateusecallback

Why the React List component gets rendered twice?


I have a React code as below:

import React, { useState, useCallback } from "react";

const initialUsers = [
  {
    id: "1",
    name: "foo",
  },
  {
    id: "2",
    name: "bar",
  },
];

const List = React.memo(({ users, onRemove }) => {
  console.log("rendering list");
  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>
          {user.name} <span onClick={() => onRemove(user.id)}>X</span>
        </li>
      ))}
    </ul>
  );
});

const App = () => {
  const [users, setUsers] = useState(initialUsers);
  const [text, setText] = useState("");
  const handleRemove = useCallback(
    (userId) => {
      console.log("handleRemove", userId);
      const filteredUsers = users.filter((user) => user.id !== userId);
      setUsers(filteredUsers);
    },
    [users]
  );
  const handleText = (event) => {
    setText(event.target.value);
  };
  return (
    <div>
      <input type="text" value={text} onChange={handleText} />
      <List users={users} onRemove={handleRemove} />
    </div>
  );
};

export default App;

When I first load the page, I am seeing the rendering list got dumped twice in the browser console, see https://codesandbox.io/s/elegant-bash-ic9uqv?file=/src/App.js

Why is that?


Solution

  • That's because you have used StrictMode in your index.js

    When the StrictMode is used, the lifecycle methods are called twice.

    It happens for detecting unexpected side effects in your lifecycle methods.

    Reference: https://reactjs.org/docs/strict-mode.html