# How do you handle useQuery with useEffect?

**URL:** <https://community.apollographql.com/t/how-do-you-handle-usequery-with-useeffect/517>\
**Category:** Client SDKs\
**Tags:** client, web\
**Created:** [June 18, 2021, 11:20am UTC](https://community.apollographql.com/t/how-do-you-handle-usequery-with-useeffect/517 "2021-06-18T11:20:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zied\_Hamdi](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/zied_hamdi/32/370_2.png) [@Zied\_Hamdi](https://community.apollographql.com/u/Zied_Hamdi)\
**Post date:** [June 18, 2021, 11:20am UTC](https://community.apollographql.com/t/how-do-you-handle-usequery-with-useeffect/517/1 "2021-06-18T11:20:43Z")

</div>

Hi all,

I feel I’m having trouble with a very basic case, but I can’t find any elegant solution.  
I need to edit a form with data coming from useQuery.  
My issue is that react imposes an order to execute hooks, and useEffect must be before useQuery, which makes it impossible for me to avoid infinite loop when setting my state directly in the component function. Here’s the code:

I could use the onCompleted() callaback but I’m pretty sure the hook was designed to work without a hack like this right?

```auto
export default function MyForm( props ) {
    const [title, setTitle] = useState()
    const { loading, data, error } = useQuery(COMPLAINT, {variables: {issueId: props.issueId}})
    const classes = useStyles()
    const {t} = useTranslation('common')

    if (loading) {
        logger.debug("loading ", props.issueId)
        return "loading..."
    }
    if (error) {
        logger.debug("error ", props.issueId, error)
        // setError(isError)
        return <div>{"error " + error}</div>;
    }
// when put here, it throws the error pasted below, if put before useQuery, it executes before data is loaded. If the code is placed directly in the function it creates an infinite loop
    useEffect(() => {
        logger.debug("checking id data is null ", data)
        if(data) {
            logger.debug("data loaded : ", data)
            issue = data.complaintById
            setTitle(issue.title)
        }
    }, [title])

    return renderEditor(state)
}

```

The error when the useEffect function is put after useQuery

```auto
Warning: React has detected a change in the order of Hooks called by EditIssue. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks

   Previous render Next render
   ------------------------------------------------------
1. useState useState
2. useState useState
3. useContext useContext
4. useReducer useReducer
5. useRef useRef
6. useRef useRef
7. useEffect useEffect
8. useEffect useEffect
9. useContext useContext
10. useDebugValue useDebugValue
11. useContext useContext
12. useRef useRef
13. useRef useRef
14. useRef useRef
15. useMemo useMemo
16. useEffect useEffect
17. useEffect useEffect
18. useDebugValue useDebugValue
19. useContext useContext
20. undefined useEffect
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    at EditIssue (http://localhost:3000/_next/static/chunks/pages/request/%5BissueId%5D/edit.js?ts=1624015172315:827:74)
    at EditRequest (http://localhost:3000/_next/static/chunks/pages/request/%5BissueId%5D/edit.js?ts=1624015172315:155935:77)
    at ThemeProvider (http://localhost:3000/_next/static/chunks/pages/_app.js?ts=1624015172315:12966:24)
    at Provider (http://localhost:3000/_next/static/chunks/pages/_app.js?ts=1624015172315:42887:24)
    at ApolloProvider (http://localhost:3000/_next/static/chunks/pages/_app.js?ts=1624015172315:6003:21)
    at App (http://localhost:3000/_next/static/chunks/pages/_app.js?ts=1624015172315:56784:24)
    at AppWithTranslation
    at ErrorBoundary (http://localhost:3000/_next/static/chunks/main.js?ts=1624015172315:677:47)
    at ReactDevOverlay (http://localhost:3000/_next/static/chunks/main.js?ts=1624015172315:781:23)
    at Container (http://localhost:3000/_next/static/chunks/main.js?ts=1624015172315:9119:5)
    at AppContainer (http://localhost:3000/_next/static/chunks/main.js?ts=1624015172315:9608:24)
    at Root (http://localhost:3000/_next/static/chunks/main.js?ts=1624015172315:9741:24)

```

---

<div class="post-metadata">

**Author:** ![mindnektar](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/mindnektar/32/259_2.png) [@mindnektar](https://community.apollographql.com/u/mindnektar)\
**Post date:** [June 18, 2021, 12:29pm UTC](https://community.apollographql.com/t/how-do-you-handle-usequery-with-useeffect/517/2 "2021-06-18T12:29:24Z")

</div>

Hi there! The error message is a bit ambiguous - here it’s not really about the order of hooks but the fact that your `useEffect` hook is conditional. Every render of your component needs to have the same number of hooks (and have them be in the same order). Your early returns in your `loading` and `error` checks cause your `useEffect` hook to be available in some renders but not in others, which conflicts with how hooks are supposed to be used. You will have to move your hook up so it’s available in every render. It doesn’t have to be before `useQuery`, though, just somewhere before the `if` statements.

This does mean that the hook may be executed before the query data is available, but that is fine - you’ll just have to handle these cases inside your `useEffect` hook, as you already seem to be doing, considering your `data` check.

---

<div class="post-metadata">

**Author:** ![Zied\_Hamdi](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/zied_hamdi/32/370_2.png) [@Zied\_Hamdi](https://community.apollographql.com/u/Zied_Hamdi)\
**Post date:** [June 18, 2021, 2:09pm UTC](https://community.apollographql.com/t/how-do-you-handle-usequery-with-useeffect/517/3 "2021-06-18T14:09:41Z")

</div>

Hello MindNektar,

Thanks for the explanations, I’m still migrating from classes to hooks, even though I knew we shouldn’t put hooks under conditions, my perception of useEffect was like it’s not really a hook, it’s just a garbage collector 🙂 😃

So yeah, it works better for me, but I still get blank pages sometimes where loading state change seems not to trigger useEffect :

```auto
function EditIssue(props) {
    const [state, setState] = useState({
            reset: true,
            workingStatus: false,
        }
    )
    const [issue, setIssue] = useState()

    useEffect(() => {
        logger.debug("checking if data is null ", data)
        if (data) {
            logger.debug("data loaded : ", data)
            setIssue({...(data.complaintById)})
        }
    }, [loading])

    const {loading, data, error} = useQuery(COMPLAINT, {variables: {issueId: props.issueId}})
    const classes = useStyles()
    const {t} = useTranslation('common')
    const router = props.router

    if (loading) {
        logger.debug("loading ", props.issueId)
        return "loading..."
    }
    if (error) {
        logger.debug("error ", props.issueId, error)
        // setError(isError)
        return <div>{"error " + error}</div>;
    }
    if (!issue)
        return "still loading"

    const cacheData = null
    let playerRef

    if (issue)
        return renderEditor(state)
}

```

I can’t figure when it works and when it hangs unnotified, one thing is kind of systematic: when I load the page from server (ssr with next) it remains blank with the message: “still loading” (and "checking if data is null " as the last log message. (I suspect it to be a timing ‘call order’ issue)

Please note that this code always works, I’m just trying to do things right since I’m migrating my old code to introduce hooks. So I’d like to use the right pattern

```auto
    const { loading, data, error } = useQuery(COMPLAINT, {variables: {issueId: props.issueId}, onCompleted:(data)=>{
            logger.debug("checking id data is null ", data)
            if(data) {
                logger.debug("data loaded : ", data)
                setIssue( {...(data.complaintById)} )
            }
        }})

```

---

<div class="post-metadata">

**Author:** ![Zied\_Hamdi](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/zied_hamdi/32/370_2.png) [@Zied\_Hamdi](https://community.apollographql.com/u/Zied_Hamdi)\
**Post date:** [June 18, 2021, 2:14pm UTC](https://community.apollographql.com/t/how-do-you-handle-usequery-with-useeffect/517/4 "2021-06-18T14:14:21Z")

</div>

Thanks for your answer, I just discovered the answer button. Now that I read the error message again, I understand it better thanks to your explanations 🙂
