Change in the order of Hooks called by <Component>
I am getting the warning about React has detected a change in the order of Hooks called by Checkout
I did read https://reactjs.org/docs/hooks-rules.html and looks like my code meets the requirements
The warning: screenshot from debbuger
Fragment of file with hooks:
if (!token) {
navigate.push(routes.login)
return <Text>Redirect</Text>
}
const maximumDate = moment().add(1, 'year')
const minimumDate = moment()
const formattedToday = minimumDate.format('YYYY-MM-DD')
const [paymentMethod, setPaymentMethod] = useState(paymentOptions[0].key)
const [totalAmount, setTotalAmount] = useState(totalCartAmount)
const [deliveryTime, setDeliveryTime] = useState(0)
const [date, setDate] = useState(minimumDate)
const [show, setShow] = useState(false)
const validationSchema = yup.object().shape({
couponCode: yup.string(),
comments: yup.string(),
})
useEffect(() => {
if (deliverySlots.length > 0) {
setDeliveryTime(deliverySlots[0].id)
}
}, [deliverySlots])
useEffect(() => {
getDeliveryTimeSlots(country.id, formattedToday, error => {
if (error) {
console.log(error)
}
})
}, [])
Full component code: https://codesandbox.io/s/modest-lewin-4x9ss
If you have hooks in your component, you must ensure that all hooks called on every render and in the same order. This code should be placed after all hooks (because of return
):
if (!token) {
navigate.push(routes.login)
return <Text>Redirect</Text>
}
I got the same error on React Native though...
After paying close attention to the error message, I realized that: I'm deleting data in my redux state from a child screen which a parent screen depends on.
e.g: ProfileScreen
=> SettingScreen
in the above example, SettingScreen
is the child screen of ProfileScreen
.
So when you delete data in your redux state that ProfileScreen
is referencing, from your SettingScreen
, you'll get the same error because ProfileScreen
useContext
is undefined from redux.
How I solved:
from:
const someTask = () => {
....
dispatch(deleteData(dataId))
navigation.navigate('HomeScreen')
}
To:
const someTask = () => {
....
navigation.navigate('HomeScreen')
dispatch(deleteData(dataId)) //deleting the Data should be the last thing to do to safely navigate away..
}
As you already listed the rules of hooks, you must have missed the important section of `Only Call Hooks at the Top Level"
It states:
Don’t call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function
Simply put, either move your hooks above the condition, or extract the condition to the parent function/component.