patternjavascriptreactMajor
"React has detected a change in the order of Hooks" but Hooks seem to be invoked in order
Viewed 0 times
hashooksdetectedtheseemreactorderbutchangeinvoked
Problem
I am trying to use
Is it that I'm generating
The full version of
An excerpt from
Context and Reducers via React's hooks, and running into problems with the order of the hooks not being constant. My understanding was that as long as the order of the useHook(…) remained the same, it was fine to invoke the returned state/update function/reducer in any sort of control flow. Otherwise, I'm invoking the hooks at the very beginning of the FunctionComponents. Is it that I'm generating
Days in a loop? Or missing something else?Warning: React has detected a change in the order of Hooks
called by Container. This will lead to bugs and errors if not fixed. For
more information, read the Rules of Hooks:
https://reactjs.org/docs/hooks-rules.html
Previous render Next render
------------------------------------------------------
1. useContext useContext
2. undefined useRef
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^The full version of
Container is below. An excerpt from Day is below, and has a ref from react-dnd's useDrop. export const Container: FunctionComponent = () => {
let events = useContext(State.StateContext)
//let events: Array = [] ) => {
return events.map(e => {
const isTodays = e.startTime.hasSame(day, "day")
return isTodays && Event.Event({ dayHeight, event: e })
})
}
let days = []
for (let i = 0; i
{getDaysEvents(day, events)}
)
}
return {days}
}
An excerpt from
Day (Event similarly uses a useDrag hook, also called at the top level just like here).const Day: FunctionComponent = ({ date, height, children }) => {
const dispatch = useContext(State.DispatchContext)
const [{ isOver, offset }, dropRef] = useDrop({
// …uses the dispatch function within…
// …
})
// …
}
Solution
Writing my comment as an answer:
The problem is that you're calling
The solution is to use JSX:
Why this works is clearer when you replace the JSX with the resulting JS code:
See https://reactjs.org/docs/react-api.html#createelement. You never want to call the function components directly, how react works is that you always hand a reference the component to react and let it call the function at the correct time.
The problem is that you're calling
Event.Event() directly, even though it is a react component. That causes react to treat the hook calls inside the function as part of Container, even though you meant for them to be part of Event.The solution is to use JSX:
return isTodays && Why this works is clearer when you replace the JSX with the resulting JS code:
return isTodays && React.createElement(Event.Event, { dayHeight, event: e })See https://reactjs.org/docs/react-api.html#createelement. You never want to call the function components directly, how react works is that you always hand a reference the component to react and let it call the function at the correct time.
Context
Stack Overflow Q#57397395, score: 64
Revisions (0)
No revisions yet.