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.