React Native Navigation - Invalid hook call - react-native

App.js:
import React, { useState } from "react";
import { Text } from "react-native";
import { NavigationContainer } from "#react-navigation/native";
import Stack from "./navigation/Stack";
export default function App() {
const [isReady, setIsReady] = useState(true);
const onFinish = () => setIsReady(true);
return isReady ? (
<NavigationContainer>
<Stack />
</NavigationContainer>
) : (
<Text>Loading...</Text>
);
}
Trying to navigate to a screen through a custom component:
import React from "react";
import { createStackNavigator } from "#react-navigation/stack";
import Home from "../screens/Home";
import Detail from "../screens/Detail";
const Stack = createStackNavigator();
export default () => (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Detail" component={Detail} />
</Stack.Navigator>
);
Im getting an error:
Invariant Violation: Invalid hook call. Hooks can only be called
inside of the body of a function component.
Can someone have a look on it?

Related

How to hide the drawer header from stack's child component?

I would like to hide drawer navigation from the list component and it still be shown in the UserHomeScreen which is the stack navigation. It works if I just use the useState, hideHeader/setHideHeader, from App.js but it is not efficient way to do this. I tried my best to look for a solution but I really can't find. I am new to react native and have a limited knowledge.
Can anyone help me how am I going do it? Please help.
BTW here is the version of my drawer: ^6.0.1, if that helps.
Thank you so much!
App.js
import React from 'react'
// components
import UserHomeScreen from './src/components/user/pages/UserHomeScreen';
import Cart from './src/components/user/pages/Cart';
import Receipt from './src/components/user/pages/Receipt';
//redux
import store from './src/redux/store'
// libraries
import { NavigationContainer } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { Provider } from 'react-redux';
const Drawer = createDrawerNavigator();
const App = () => {
const [hideHeader, setHideHeader] = React.useState(false);
return (
<Provider store={store}>
<NavigationContainer>
{/* this hide drawer */}
{/* options={{headerShown: false}} */}
<Drawer.Navigator >
<Drawer.Screen name="Home" >
{() => <UserHomeScreen setHideHeader={setHideHeader} />}
</Drawer.Screen>
<Drawer.Screen name="Cart" component={Cart} />
<Drawer.Screen name="Receipt" component={Receipt} />
</Drawer.Navigator>
</NavigationContainer>
</Provider>
)
}
export default App;
UserHomeScreen.js
import React from 'react'
import List from '../components/User Home Screen/List';
import { createStackNavigator } from '#react-navigation/stack';
import ItemDetails from '../components/User Home Screen/ItemDetails';
import { useNavigation } from '#react-navigation/native';
import { Button } from 'react-native';
const Stack = createStackNavigator();
const UserHomeScreen = () => {
function backHandler(){
navigation.navigate('List')
}
// this hide the drawer header but I want it inside the list
// but if I do, the stack header that hides not the drawer header.
// React.useEffect(() => {
// navigation.setOptions({
// headerShown: false
// });
// })
const navigation = useNavigation();
return (
<Stack.Navigator>
<Stack.Screen name='List' component={List}>
</Stack.Screen>
<Stack.Screen name='Item Details' component={ItemDetails}
options={{
headerLeft: () => <Button title='Back' onPress={backHandler}/>
}}
/>
</Stack.Navigator>
)
}
export default UserHomeScreen;

React Native : my component isn't detected as a component

I'm started with React Native and try to use the navigation between screns. To do so I creat a component Navigation but when I want to use it this error show up :
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined
It appear to be the component AppNavigator that is the issue
I tried :
checked all my exports and import and for me their is no problems
change my const component in a function component but nothing do the trick.
Can you help me ?
App.js :
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import AppNavigator from './components/navigation';
function App() {
return (
<View>
<AppNavigator />
</View>
);
}
/*const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
},
});*/
export default App;
Navigation.js
import React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigatorContainer } from '#react-navigation/native';
import Localisation from './localisation';
import Home from './home';
const { Navigator, Screen } = createStackNavigator()
const AppNavigator = () => (
<NavigatorContainer>
<Navigator initialRouteName="Home">
<Screen options={{headerShown: false}} name="Home" component={Home} />
</Navigator>
</NavigatorContainer>
)
export default AppNavigator;
There is no component named NavigatorContainer in react-navigation/native. The component is called NavigationContainer.
Hence, the following should fix the issue.
import React from 'react';
import { createStackNavigator } from '#react-navigation/stack';
import { NavigationContainer } from '#react-navigation/native';
import Localisation from './localisation';
import Home from './home';
const { Navigator, Screen } = createStackNavigator()
const AppNavigator = () => (
<NavigationContainer>
<Navigator initialRouteName="Home">
<Screen options={{headerShown: false}} name="Home" component={Home} />
</Navigator>
</NavigationContainer>
)
export default AppNavigator;

How does this V4 Navigation look like now it's V6?

I would like to convert the following react-navigation code (v4) to v6. What will the following now look like? This is in each of my screens.
import { withNavigation } from "react-navigation";
import { TransitionPresets } from 'react-navigation-stack';
const styles = StyleSheet.create({
...
)}
OtpScreen.navigationOptions = () => {
return {
header: () => null,
...TransitionPresets.SlideFromRightIOS,
}
}
export default withNavigation(MyScreen);
According to the doc, you can add your options directly inside the navigator definition.
After install the npm packages, for a stack navigator try this:
import { createStackNavigator } from '#react-navigation/stack';
import { TransitionPresets } from '#react-navigation/stack';
...
const Stack = createStackNavigator();
export default function MyStack() {
return (
<Stack.Navigator screenOptions ={... // your global options here}>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen
name="Profile"
component={Profile}
options={{
...TransitionPresets. SlideFromRightIOS,
... // others specific options
}}
/>;
</Stack.Navigator>
);
}
Then in your App.js
import { NavigationContainer } from '#react-navigation/native';
import MyStack from ../path/to/file
... // others imports
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
)
}
WithNavigation has been removed since v5.
Here is the link to the doc

How to access redux action while using connect() and NavigationContainer

I'm working on a React Native project using Redux and NavigationContainer. I was using useSelector(), useDispatch() and everything was working fine.
To move forward, we have to use connect(mapStateToProps, mapDispatchToProps)(Component); instead of useSelector() and useDispatch().
From what I understand while reading articles and docs, I can access both state values and actions from props in the same component that I passed into connect().
In my case, the only parameter I can find is ({navigation, route}), I can access the state like this: route.params. I tried to access the actions with navigation and route, which unfortunately didn't work.
connect.js
import {
login,
loggout,
} from './redux/actions';
export const mapStateToProps = state => ({
auth: state.auth,
});
const ActionCreators = Object.assign(
{},
login,
loggout,
);
export const mapDispatchToProps = dispatch => ({
actions: bindActionCreators(ActionCreators, dispatch),
});
App.js
import {Provider} from 'react-redux';
import {PersistGate} from 'redux-persist/integration/react';
import Main from './Main';
import configureStore from './store';
const App = () => {
const {store, persistor} = configureStore();
return (
<Provider store={store}>
<PersistGate persistor={persistor}>
<Main />
</PersistGate>
</Provider>
);
};
export default App;
Main.js
import {connect} from 'react-redux';
import {mapStateToProps, mapDispatchToProps} from './connect';
import {NavigationContainer} from '#react-navigation/native';
import {createNativeStackNavigator} from '#react-navigation/native-stack';
import Login from './screens/Login';
export const Main = () => {
const Stack = createNativeStackNavigator();
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Login"
screenOptions={{
headerTransparent: true,
headerTintColor: colors.yellow,
}}>
<Stack.Screen
name="Login"
component={Login}
options={{headerShown: false}}
initialParams={props}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
export default connect(mapStateToProps, mapDispatchToProps)(Main);
Login.js
import {login} from '../redux/actions';
import {
View,
Text,
} from 'react-native';
const Login = ({navigation, route}) => {
console.log('from Login');
console.log(route.params); // state access
// Here, how can I access the redux actions?
console.log('-----------------');
return (
<View style={styles.container}>
{route.params.auth.status === 'logged in' ? (
<Text>Go To Profile</Text>
) : (
<Text>Stay Here</Text>
)}
</View>
);
};
The issue is, I can't access redux actions using props. How can I access them? Does NavigationContainer works with connect()? If I'm not using NavigatorContainer I can access an action like: props.actionName(), but with navigation is another situation.

navigation.navigate is not a function problem in react-navigation

hello i tried to use react Navigation from its docs but i have a problem.the error is navigation.navigate is undefined here is my declaration my routes:
import 'react-native-gesture-handler';
import React from 'react';
import {
SafeAreaView,
StyleSheet,
} from 'react-native';
import { createStackNavigator } from '#react-navigation/stack'
import { createAppContainer } from 'react-navigation';
import { NavigationContainer } from '#react-navigation/native';
import AboutUs from './AboutUs'
import Navigations from './Navigations'
const App: () => React$Node = () => {
const Stack = createStackNavigator();
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="App" component={App} />
<Stack.Screen name="AboutUs" component={AboutUs} />
<Stack.Screen name="Navigations" component={Navigations} />
</Stack.Navigator>
</NavigationContainer>
);
};
and here is my Button to navigate:
import React from 'react'
import {
View, Text,
Button
} from 'react-native'
const AboutUs = ({ navigation }) => {
return <View>
<Text>About us page</Text>
<Button title='press me' onPress={() => { navigation.navigate('Navigations', name = 'aliiiiiiiiis') }} />
</View>
}
export default AboutUs;