Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Too many re-renders with React Hooks

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!

like image 422
SrdjaNo1 Avatar asked Oct 27 '19 23:10

SrdjaNo1


People also ask

How do I stop re-rendering in React hooks?

Use React. memo() to prevent re-rendering on React function components.

How do I stop infinite rendering in React?

To get rid of your infinite loop, simply use an empty dependency array like so: const [count, setCount] = useState(0); //only update the value of 'count' when component is first mounted useEffect(() => { setCount((count) => count + 1); }, []); This will tell React to run useEffect on the first render.

Why does React keep Rerendering?

React's “main job” is to keep the application UI in sync with the React state. The point of a re-render is to figure out what needs to change.


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(...);
like image 167
Nick Avatar answered Oct 18 '22 20:10

Nick