2

I am trying to set the state of a variable "workspace", but when I console log the data I get an infinite loop. I am calling the axios "get" function inside of useEffect(), and console logging outside of this loop, so I don't know what is triggering all the re-renders. I have not found an answer to my specific problem in this question. Here's my code:

function WorkspaceDynamic({ match }) {
  const [proposals, setProposals] = useState([{}]);
  useEffect(() => {
    getItems();
  });

  const getItems = async () => {
    const proposalsList = await axios.get(
      "http://localhost:5000/api/proposals"
    );
    setProposals(proposalsList.data);
  };

  const [workspace, setWorkspace] = useState({});
  function findWorkspace() {
    proposals.map((workspace) => {
      if (workspace._id === match.params.id) {
        setWorkspace(workspace);
      }
    });
  }

Does anyone see what might be causing the re-render? Thanks!

  • I think useEffect causing the re-render, in short, add useEffect(()=> {getItems(); }, [getItem] ); instead of your construction with useEffect. In details, you can try to read https://stackoverflow.com/questions/53070970/infinite-loop-in-useeffect or https://medium.com/@andrewmyint/infinite-loop-inside-useeffect-react-hooks-6748de62871 – Alexey Nazarov Sep 22 '20 at 20:24

3 Answers3

5

The effect hook runs every render cycle, and one without a dependency array will execute its callback every render cycle. If the effect callback updates state, i.e. proposals, then another render cycle is enqueued, thus creating render looping.

If you want to only run effect once when the component mounts then use an empty dependency array.

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

If you want it to only run at certain time, like if the match param updates, then include a dependency in the array.

useEffect(() => {
  getItems();
}, [match]);
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
2

Your use of useEffect is not correct. If you do not include a dependency array, it gets called every time the component renders. As a result your useEffect is called which causes setProposals then it again causes useEffect to run and so on

try this

useEffect(() => {
    getItems();
  } , []);   // an empty array means it will be called once only
Mike Szyndel
  • 10,461
  • 10
  • 47
  • 63
Mohammad Faisal
  • 2,265
  • 1
  • 10
  • 16
0

I think it's the following: useEffect should have a second param [] to make sure it's executed only once. that is:

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

otherwise setProposal will modify the state which will trigger a re-render, which will call useEffect, which will make the async call, which will setProposal, ...

user103716
  • 190
  • 12