question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

React has detected a change in the order of Hooks called by InfiniteScroll while rendering List

See original GitHub issue

I see following error when I render a list. There are no if/else in the component which usually lead to such problem. Although the app works fine, I would still like to resolve the warning from React.

index.js:1 Warning: React has detected a change in the order of Hooks called by InfiniteScroll. 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. useMemo                    useMemo
3. useState                   useState
4. useState                   useState
5. useState                   useState
6. useRef                     useRef
7. useRef                     useRef
8. useEffect                  useEffect
9. useEffect                  useEffect
10. useLayoutEffect           useLayoutEffect
11. useLayoutEffect           useLayoutEffect
12. useMemo                   useMemo
13. useMemo                   useMemo
14. useContext                useContext
15. useContext                useContext
16. useContext                useContext
17. useContext                useContext
18. useContext                useContext
19. undefined                 useContext
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    at InfiniteScroll (http://localhost:3000/static/js/0.chunk.js:127046:23)
    at ul
    at List__StyledList (http://localhost:3000/static/js/0.chunk.js:287813:6)
    at Keyboard (http://localhost:3000/static/js/0.chunk.js:127456:22)
    at List (http://localhost:3000/static/js/0.chunk.js:128704:21)
    at div
    at StyledBox (http://localhost:3000/static/js/0.chunk.js:287813:6)
    at Box (http://localhost:3000/static/js/0.chunk.js:111636:24)
    at div
    at StyledBox (http://localhost:3000/static/js/0.chunk.js:287813:6)
    at Box (http://localhost:3000/static/js/0.chunk.js:111636:24)
    at AlarmList (http://localhost:3000/static/js/main.chunk.js:26446:81)
    at div
    at StyledBox (http://localhost:3000/static/js/0.chunk.js:287813:6)
    at Box (http://localhost:3000/static/js/0.chunk.js:111636:24)
    at div
    at StyledGrid (http://localhost:3000/static/js/0.chunk.js:287813:6)
    at Grid (http://localhost:3000/static/js/0.chunk.js:125695:25)
    at div
    at StyledGrommet (http://localhost:3000/static/js/0.chunk.js:287813:6)
    at Grommet (http://localhost:3000/static/js/0.chunk.js:126192:29)
    at MainApp (http://localhost:3000/static/js/main.chunk.js:30776:89)
    at App (http://localhost:3000/static/js/main.chunk.js:25743:101)
    at Provider (http://localhost:3000/static/js/0.chunk.js:264837:20)

The code structure in the component is something like below:

import React, { useRef, useState } from 'react'
import { Box, List, Button, Drop } from 'grommet'
import { Alarm, InProgress } from 'grommet-icons'
import AlarmSummary from './AlarmSummary'
import { useDispatch, useSelector } from 'react-redux'
import { ActionCreators, Selectors } from 'shared'
import NewAlarmContainer from './NewAlarmContainer'
import EditAlarm from './EditAlarm'
import { Constants, I18n } from 'config'

const AlarmList = () => {
  const alarms = useSelector(state => Selectors.allAlarmsSelector(state))

  const dispatch = useDispatch()

  const newTimerButtonRef = useRef(null)

  const [showNewAlarmWindow, setShowNewAlarmWindow] = useState(false)
  const displayNewAlarmWindow = () => setShowNewAlarmWindow(true)
  const hideNewAlarmWindow = () => setShowNewAlarmWindow(false)

  return (
    <Box flex>
      <Box direction="row" justify="between">
        <Button
          plain
          color="brand"
          label={I18n.t('newAlarm')}
          margin={{ horizontal: '40px', top: '20px', bottom: '10px' }}
          onClick={() => dispatch(ActionCreators.setShowNewAlarmWizard(true))}
          icon={<Alarm color="brand" />}
          alignSelf="start"
        />
        <Button
          ref={newTimerButtonRef}
          plain
          label={I18n.t('quickAlarm')}
          color="brand"
          margin={{ horizontal: '40px', top: '20px', bottom: '10px' }}
          onClick={displayNewAlarmWindow}
          icon={<InProgress color="brand" />}
          alignSelf="start"
        />
      </Box>
      <Box>
        <List border={false} data={alarms} children={AlarmSummary} />
      </Box>
      {showNewAlarmWindow && (
        <Drop
          onEsc={hideNewAlarmWindow}
          onClickOutside={hideNewAlarmWindow}
          target={newTimerButtonRef.current}
          align={{ top: 'top', left: 'right' }}>
          <NewAlarmContainer
            targetComponent={EditAlarm}
            alarmType={Constants.AlarmTypes.CASCADING}
          />
        </Drop>
      )}
    </Box>
  )
}

export default AlarmList

The warning seems to be arising from the InfiniteScroll component. I am sorry I am not able to provide a reproduction in sandbox. It works i normal operation. The alarms array here is hooked to a list redux store which is empty to begin with and then the data is fetched from a Firebase database and updated on the redux store. Since it is a realtime database, the alarms array in the redux store are updated multiple times

Expected Behavior

No warning that a change in order of hooks is detected.

Actual Behavior

Warning is seen as shown above.

Your Environment

  • Grommet version: 2.16.3
  • Browser Name and version: Chrome
  • Operating System and version (desktop or mobile): MacOS desktop

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
britt6612commented, Apr 6, 2021

@varungupta85

I spent today looking and understanding the codesandbox that you had linked. After spending some time looking at infinite scroll there was nothing that stood out to me so I went back to your code and noticed that when I commented out these lines in app.js

  const [editCategoryColor, setEditCategoryColor] = useState(false);
  const [editCategory, setEditCategory] = useState(false);

Everything worked fine. So this led to thinking there was something with how setting state was being done. In the AlarmsByCategoriesList you are passing children={AlarmsByCategorySummary} so once the code was moved in line instead of calling the AlarmsByCategorySummary I could see there was a react error.

Screen Shot 2021-04-05 at 9 10 26 PM

https://codesandbox.io/s/flagged-usestate-h9qyw

It was throwing an error because the useState was being called inside a callback when it was being passed through. So instead of setting the state with the callback the AlarmCard is going to be returned in which the state will no longer be set while inside the callback.

Let me know if you have any questions or need clarity on anything. https://codesandbox.io/s/working-fix-hooks-4bqcu?file=/src/App.js

1reaction
varungupta85commented, Apr 7, 2021

Makes sense @britt6612. Good lesson learnt.

Read more comments on GitHub >

github_iconTop Results From Across the Web

"React has detected a change in the order of Hooks" but ...
I ran into this same error message in a component I was writing due to use of short-circuiting logic. This resulted in an...
Read more >
How to overcome warning 'React has detected a change in ...
A look at a functional component that under non-obvious circumstances triggers this React Hooks warning.
Read more >
[Solved]-"React has detected change in order of hooks", ...
Your understanding of hooks usage is correct and the most likely issue is that your getTimesForCurrentDate function is using useState hook conditionally.
Read more >
React Hooks for infinite scroll: An advanced tutorial
React Hooks for infinite scroll: An advanced tutorial · As we're using a single variable to keep track of the most recently loaded...
Read more >
Intersection Observer API - MDN Web Docs
Implementing "infinite scrolling" web sites, where more and more content is loaded and rendered as you scroll, so that the user doesn't have...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found