React has detected a change in the order of Hooks called by InfiniteScroll while rendering List
See original GitHub issueI 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:
- Created 3 years ago
- Comments:9 (1 by maintainers)
Top GitHub Comments
@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.jsEverything worked fine. So this led to thinking there was something with how setting state was being done. In the
AlarmsByCategoriesList
you are passingchildren={AlarmsByCategorySummary}
so once the code was moved in line instead of calling theAlarmsByCategorySummary
I could see there was a react error.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 theAlarmCard
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
Makes sense @britt6612. Good lesson learnt.