Toseef Ahmad
Toseef Ahmad

Reputation: 23

React js using hooks useState infinite loop rendering?

I want to update my component current state on result by using custom hook but when i update it showing me infinite loop rendering. by using useState() hook. I am new to react hooks.

import React, { useMemo, useState, useReducer, useEffect, useCallback } from 'react';
import getAllFaqs from './faqQuery.graphql';
import { useFaq } from '../../peregrine/talons/Faq/useFaq';

const Faq = props => {
  const [state, setState] = useState({})
  const talonProps = useFaq({
    query: getAllFaqs
  });
  const { data, error, loading } = talonProps;
  setState({data})

  console.log("Thank data", state)
  return (<div>its Working</div>);
};

Upvotes: 1

Views: 2955

Answers (3)

Peter
Peter

Reputation: 1249

Dont setState in the functional component directly. Use onCompleted event:

import React, { useMemo, useState, useReducer, useEffect, useCallback } from 'react';
import getAllFaqs from './faqQuery.graphql';
import { useFaq } from '../../peregrine/talons/Faq/useFaq';

const Faq = props => {
  const [state, setState] = useState({})
  const talonProps = useFaq({
    query: getAllFaqs,
    onCompleted: ({ data, error, loading }) => setState({data})
  });

  console.log("Thank data", state)
  return (
    <div>its Working</div>
  );
};

Upvotes: 1

Trey Eckels
Trey Eckels

Reputation: 348

Try running the following code in a useEffect hook:

const talonProps = useFaq({
  query: getAllFaqs
});
const { data, error, loading } = talonProps;
setState({data})

That would look like:

import React, { useMemo, useState, useReducer, useEffect, useCallback } from 'react';
import getAllFaqs from './faqQuery.graphql';
import { useFaq } from '../../peregrine/talons/Faq/useFaq';

const Faq = props => {
  const [state, setState] = useState({})
  
  useEffect(() => {
    const talonProps = useFaq({
      query: getAllFaqs
    });
     const { data, error, loading } = talonProps;
     setState({data})
     console.log("Thank data", state)
  }, [])

  return (<div>its Working</div>);
};

What's happening is every time the component renders, it calls your query and sets state, causing the component to re-render again, which calls your query and sets state, causing the component to re-render again ... Using useEffect with the second parameter being an empty array will make your component call your query when the component first renders and set state only once.

Upvotes: 1

blankart
blankart

Reputation: 716

You are calling the setState({data}) everytime your component loads. Try putting the setState inside a useEffect.

useEffect(() => {
setState({ data })
}, [data])

Upvotes: 0

Related Questions