So as preface I am learning react-native and I am developing an app which connects to an backend api using redux.
I am getting the following error when I try to run the app.
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
This error is located at:
in ComplaintsMenu (created by HomePage)
in RCTView (created by View)
in View (created by HomePage)
in RCTView (created by View)
in View (created by HomePage)
in HomePage (created by SceneView)
in StaticContainer
in EnsureSingleNavigator (created by SceneView)
in SceneView (created by CardContainer)
in RCTView (created by View)
in View (created by CardContainer)
in RCTView (created by View)
in View (created by CardContainer)
in RCTView (created by View)
in View
in CardSheet (created by Card)
in RCTView (created by View)
in View (created by AnimatedComponent)
in AnimatedComponent
in AnimatedComponentWrapper (created by PanGestureHandler)
in PanGestureHandler (created by PanGestureHandler)
in PanGestureHandler (created by Card)
in RCTView (created by View)
in View (created by AnimatedComponent)
in AnimatedComponent
in AnimatedComponentWrapper (created by Card)
in RCTView (created by View)
in View (created by Card)
in Card (created by CardContainer)
in CardContainer (created by CardStack)
in RNSScreen (created by AnimatedComponent)
in AnimatedComponent
in AnimatedComponentWrapper (created by InnerScreen)
in Suspender (created by Freeze)
in Suspense (created by Freeze)
in Freeze (created by DelayedFreeze)
in DelayedFreeze (created by InnerScreen)
in InnerScreen (created by Screen)
in Screen (created by MaybeScreen)
in MaybeScreen (created by CardStack)
in RNSScreenContainer (created by ScreenContainer)
in ScreenContainer (created by MaybeScreenContainer)
in MaybeScreenContainer (created by CardStack)
in RCTView (created by View)
in View (created by Background)
in Background (created by CardStack)
in CardStack (created by HeaderShownContext)
in RNCSafeAreaProvider (created by SafeAreaProvider)
in SafeAreaProvider (created by SafeAreaInsetsContext)
in SafeAreaProviderCompat (created by StackView)
in RNGestureHandlerRootView (created by GestureHandlerRootView)
in GestureHandlerRootView (created by StackView)
in StackView (created by StackNavigator)
in PreventRemoveProvider (created by NavigationContent)
in NavigationContent
in Unknown (created by StackNavigator)
in StackNavigator (created by App)
in EnsureSingleNavigator
in BaseNavigationContainer
in ThemeProvider
in NavigationContainerInner (created by App)
in RCTView (created by View)
in View (created by SafeAreaWrap)
in SafeAreaWrap (created by App)
in Provider (created by App)
in App (created by withDevTools(App))
in withDevTools(App)
in RCTView (created by View)
in View (created by AppContainer)
in RCTView (created by View)
in View (created by AppContainer)
in AppContainer
in main(RootComponent)
my reducer is-
export function complaintReducer(state = initalComplaintsFormState, action) {
switch (action.type) {
//...other cases
case GET_COMPLAINT_LIST:
return { ...state, complaintList: action.payload };
default:
return state;
}
}
and my ComplaintsMenu
component has the following code-
//...other imports
import { useSelector, useDispatch } from "react-redux";
import { getComplaintList } from "../Redux/Actions";
export default function ComplaintsMenu() {
const { ComplaintList } = useSelector((state) => state.complaintReducer);
const dispatch = useDispatch;
----------
// From my understanding this is where the issue is, since the dispatch function (hook?) is being called conditionally under the useEffect hook. but I don't understand what exactly is happening and how to implement what I am trying to implement, I followed steps from the youtube video mentioned below where he did the same thing
useEffect(() =\> {
dispatch(getComplaintList());
}, \[\]);
return (
\<FlatList
data={ComplaintList}
renderItem={({ item }) =\> (
\<ComplaintCard
key={item.complaint_id}
title={item.issue}
status={item.status}
/\>
)}
/\>
);
these are my dependencies version
{
"name": "poll-app",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
},
"dependencies": {
"@expo-google-fonts/inter": "^0.2.2",
"@expo/webpack-config": "^0.17.2",
"@react-navigation/native": "^6.1.3",
"@react-navigation/stack": "^6.3.12",
"expo": "\~47.0.12",
"expo-status-bar": "\~1.4.2",
"react": "18.1.0",
"react-dom": "18.1.0",
"react-native": "0.70.5",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "\~3.18.0",
"react-native-web": "\~0.18.9",
"react-redux": "^8.0.5",
"redux": "^4.2.1",
"redux-thunk": "^2.4.2"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"eslint-plugin-react-hooks": "^4.6.0"
},
"private": true
}
Note: I am using an older version of node because expo had some legacy dependency issue with the current lts version of node
I have tried This answer, I believe my question is a duplicate of this question, I don’t know how to revive unanswered questions so I am asking this question here, I apologize if this is not the correct way to ask for the answer on stack.
I followed this Youtube tutorial for the implementation
As of now
- I have reinstalled
react-redux
andredux
and also triednpm update
. - To check for the react version mismatch issue. I have also verified that all the dependencies use the same react version.
I have included my thoughts about the problem in the a comment in the code above
>Solution :
try like this const dispatch = useDispatch()
, you’re not calling the function useDispatch