Too many re-renders with React Hooks

Viewed 23857

Similar questions have been asked but I haven't found a solution for this particular one. I have one component which renders all boards and I am using a custom useFetch hook to fetch all boards.

const BoardsDashboard = () => {

  let [boards, setBoards] = useState([]);

  const { response } = useFetch(routes.BOARDS_INDEX_URL, {});

  setBoards(response);

  return (
    <main className="dashboard">
      <section className="board-group">
        <header>
          <div className="board-section-logo">
            <span className="person-logo"></span>
          </div>
          <h2>Personal Boards</h2>
        </header>

        <ul className="dashboard-board-tiles">
          {boards.map(board => (
            <BoardTile title={board.title} id={board.id} key={board.id} />
          ))}
          <CreateBoardTile />
        </ul>
    
      </section>
    </main>
  );
};

const useFetch = (url, options) => {
  const [response, setResponse] = useState([]);
  const [error, setError] = useState(null);
  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await fetch(url, options);
        const json = await res.json();
        setResponse(json);
      } catch (error) {
        setError(error);
      }
    };
    fetchData();
  }, []);
  return { response, error };
};

I am getting too many re-renders due to setBoards(response) line. What is the right way to handle this?

Thanks!

1 Answers

Sounds like you might want a useEffect hook to take action when response is updated.

useEffect(() => {
  setBoards(response);
}, [response]);

Note: if you have no need to ever change the boards state, then maybe it doesn’t need to be stateful at all, you could just use the returned value from your useFetch hook and be done with it.

const { response: boards } = useFetch(...);
Related