简体   繁体   中英

How to solve React "too many re-renders" error

I'm learning about React hooks and have the following code:

import React, { useState, useEffect } from "react";
import "./App.css";

function App() {

  const [count, setCount] = useState(0);
  const [person, setPerson] = useState([]);

  useEffect(() => {
    getPerson();
  }, []);

  const getPerson = async () => {
    const response = await fetch("https://api.randomuser.me");
    const data = await response.json();
    setPerson(data.results);
  };

  return (
    <div className="App">
      <p>You clicked {count} times</p>
      <button onClick={() => getPerson(), setCount(count + 1)}>Click Me</button>
      <div>{person.map(person => person.name.first)}</div>
    </div>
  );
}

export default App;

When I click the 'Click Me' button, I want the counter to update and the API call to be made to fetch a random person. Individually, both of these bits of code work. However, when I try to do both at the same time, I receive this error: Too many re-renders. React limits the number of renders to prevent an infinite loop. Too many re-renders. React limits the number of renders to prevent an infinite loop.

I am new to React and can't figure why this is. I have added the [] as the second argument in the UseEffect method which I thought might stop the page constantly re-rendering.

Can anyone help? Thanks!

Not sure if you copied the code wrong to your question, but here is something that will make it better.

  ...
  return (
    <div className="App">
      <p>You clicked {count} times</p>
      <button onClick={() => { getPerson(); setCount(count + 1)}}>Click Me</button>
      <div>{person.map(person => person.name.first)}</div>
    </div>
  );

This will work, but at the same time, isn't good, maybe you want to increase the count only when the resquet finishes?

So what you can do is use .then

onClick={() => { getPerson().then(() => setCount(count + 1))}}

This isn't correct because useEffect is nothing but similar to componentDidMount and componentDidUpdate . If you are updating state in this method and not restricting it then it will cause infinite rendering.

import React, { useState, useEffect } from "react";
import "./App.css";

function App() {
  const [count, setCount] = useState(0);
  const [person, setPerson] = useState([]);

  useEffect(() => {
    // You need to restrict it at some point
    // This is just dummy code and should be replaced by actual
    if (person.length === 0) {
        getPerson();
    }
  }, []);

  const getPerson = async () => {
    const response = await fetch("https://api.randomuser.me");
    const data = await response.json();
    setPerson(data.results);
  };

  return (
    <div className="App">
      <p>You clicked {count} times</p>
      <button onClick={() => {getPerson(); setCount(count + 1);}}>Click Me</button>
      <div>{person.map(person => person.name.first)}</div>
    </div>
  );
}

export default App;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM