How to navigate one page to another in react native. Here I want to navigate to my activity to another activity, When i click on list item this will navigate to another page You can check my code below
import React, {Component} from 'react';
import { StyleSheet, View, AppRegistry,} from 'react-native';
import { List, ListItem, Icon, Text } from 'native-base';
import { StackNavigator } from 'react-navigation';
import Adjective from './Topic/Adjective';
class BasicFlatList extends Component {
onSourcesSetting = () => {
this.props.navigation.navigate('Adj');
}
render(){
return(
<List>
<ListItem
button
noBorder
onPress={() => this.onSourcesSetting}>
<Text>Adjective</Text>
</ListItem>
</List>
);
}
}
const App = StackNavigator({
Adj: Adjective,
});
export default BasicFlatList;
You can create a new screen(component) and pass the name of that route and other required parameters to the function.
import React, {Component} from 'react';
import { StyleSheet, View, AppRegistry,} from 'react-native';
import { List, ListItem, Icon, Text } from 'native-base';
import { StackNavigator } from 'react-navigation';
import Adjective from './Topic/Adjective';
class BasicFlatList extends Component {
onSourcesSetting = () => {
this.props.navigation.navigate('AdjDetail', {
// require params(maybe adj id)
});
}
render(){
return(
<List>
<ListItem
button
noBorder
onPress={() => this.onSourcesSetting}>
<Text>Adjective</Text>
</ListItem>
</List>
);
}
}
class AdjectiveDetail extends React.Component {
render() {
console.log("props", this.props);
return null;
}
}
const App = StackNavigator({
Adj: Adjective,
AdjDetail: AdjectionDetail
});
export default BasicFlatList;
From the code i guess you are using react-navigation. You can go through the documentation for more details
P.S: react-native creates a single activity and entire app is run inside the single activity, there is no such thing as navigate from one activity to another like in android.
Related
I am having a little trouble accessing this.props.navigation.navigate in child pages within ViewPager. I have a page where there's a button called "Details" and upon clicking the button it should open up a new separate view (like a new Intent Activity).
Structure is:
Login page -> tap on "login" button -> opens MainPage having a custom CustomBottomNavigationBar with ViewPager component which takes {Object} of 5 different pages and renders them like:
In the root App.js I've already defined this configuration:
// App.js
import MainPage from './views/mainpage';
import PageOne from './views/pageoneview';
import PageTwo from './views/pagetwoview';
import PageOneDetailView from './views/PageOneDetailView';
const MainNavigator = createStackNavigator({
Home: {screen: MainPage},
PageOne: {screen: PageOne},
PageTwo: {screen: PageTwo},
PageOneDetailView: {screen: PageOneDetailView}
},
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
// mainpage.js
import React, { Component } from 'react';
import {
StyleSheet,
Image,
View,
TouchableOpacity,
ToastAndroid
} from 'react-native';
import PageOne from './homepages/pageoneview';
import PageTwo from './homepages/pagetwoview';
import CustomBottomNavigationBar from './../components/CustomBottomNavigationBar';
export default MainPage extends Component {
constructor(props) {
super(props);
}
screens = () => {
return {
p1: {page: <PageOne/>},
p2: {page: <PageTwo/>}
}
}
render() {
return (
<CustomBottomNavigationBar
screensets={this.screens()}
/>
);
}
}
Now in PageOne.js there is a button called "Details" and on tapping, it must open a new PageOneDetail.js
// pageoneview.js
import React, { Component } from 'react';
import {
StyleSheet,
Image,
View,
TouchableOpacity,
ToastAndroid
} from 'react-native';
import PageOneDetail from './homepages/PageOneDetailView';
export default PageOne extends Component {
constructor(props) {
super(props);
}
OpenView = (navigateObject, whichScreen) => {
navigateObject(whichScreen);
}
render() {
const {navigate} = this.props.navigation;
return (
<View style={{ flex: 1, alignSelf: 'flex-end' }}>
<TouchableOpacity onPress={() => this.OpenView(navigate, 'PageOneDetailView')}>
<Text> Details </Text>
</TouchableOpacity>
</View>
);
}
}
The error I get when I land on the MainPage is: undefined is not an object this.props.navigation.navigate when mainpage.js tries to load pageoneview.js
Please help me understanding how to fix this issue which I have been facing whole day.
Thanks.
The navigation prop is only accessible to screens, not children of those screens. You can pass down the navigation from the parent or use withNavigation HOC or useNavigation hook from react-navigation-hooks to access it everywhere.
What could be the reason that content in Tab is not displayed?
I Receive a blank white box.
When I have only export const TopNavTabs without the class App it works but I need this as a component.
import React, { Component } from 'react'
import { Platform, View } from 'react-native'
import { TabNavigator } from 'react-navigation'
import General from './components/tabs/General'
import Help from './components/tabs/Help'
import Tips from './components/tabs/Tips'
export const TopNavTabs = TabNavigator({
General: { screen: General },
Help: { screen: Help },
Tips: { screen: Tips },
},
{
animationEnabled:true
});
export default class App extends Component{
render(){
return(
<View>
<TopNavTabs />
</View>
)
}
}
index.js
import React, {Component} from 'react';
import {AppRegistry, Text, View} from 'react-native';
import App from './src/App';
export default class Test extends Component {
render() {
return (
<App />
);
}
}
AppRegistry.registerComponent('test', () => Test);
While writing a demo stacknavigation app I am encountering an error on semulator stating
" Route 'Main' should declare a screen. For example:
import MyScreen from './MyScreen';
...
Main: {
screen: MyScreen,
}
C:\RN\blog\node_modules\react-navigation\src\routers\validateRouteConfigMap.js:23:8
validateRouteConfigMap
C:\RN\blog\node_modules\react-navigation\src\routers\validateRouteConfigMap.js:18:21
default
C:\RN\blog\node_modules\react-navigation\src\routers\StackRouter.js:47:25
default
C:\RN\blog\node_modules\react-navigation\src\navigators\StackNavigator.js:51:29
......
"
Why this is happening I don't know can anybody has any idea ?
The remain code are below
import React from 'react';
import { Text, View } from 'react-native';
import MainScreen from './MainScreen';
import RegisterScreen from './RegisterScreen';
import { StackNavigator } from 'react-navigation';
const ScreenList = StackNavigator({
Main: {
screen: MainScreen,
},
Register: {
screen: RegisterScreen,
},
});
export default ScreenList;
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
import MainScreen from './src/screens/MainScreen';
import ScreenList from './src/screens/ScreenList';
export default class App extends Component<{}> {
render() {
return (
<View>
<ScreenList />
</View>
);
}
}
import React, { Component } from 'react';
import { View, Text } from 'react-native';
import { Card, Button, CardSection } from '../components/common/Index';
import Login from '../components/Login';
import ScreenList from './ScreenList';
export default class MainScreen extends Component {
render() {
return (
<View>
<Card>
<Login />
</Card>
<Text>----------------------------------</Text>
<Card>
<CardSection>
<Button>Register</Button>
</CardSection>
</Card>
</View>
);
}
}
Maybe its an issue with imports. Try removing
import MainScreen from './src/screens/MainScreen';
from App.js or wherever it is. It should work.
A guess, maybe you have not exported MainScreen Component.It will help if you can share the mainScreen file code.
I'm using React Router for a React Native app. Not sure what I'm missing here but I install react-router-native and require the history package, and setup a couple methods that just push a new route onto the stack but nothing happens. I console.log('clicked'); to check that it's firing and it is so not sure what's wrong.
import React, { Component } from 'react';
import { View } from 'react-native';
import Splash from './Splash';
import createHistory from 'history/createMemoryHistory';
const history = createHistory();
class SplashContainer extends Component {
goToLogin = () => {
history.push('/Login');
}
goToRegister = () => {
history.push('/SignUp');
}
render () {
console.log(history)
return (
<Splash
goToLogin={this.goToLogin}
goToRegister={this.goToRegister}
/>
);
}
}
export default SplashContainer;
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { Button } from 'native-base';
import { Link } from 'react-router-native';
import PropTypes from 'prop-types';
const Splash = (props) => {
console.log(props)
return (
<View style={styles.container}>
<Button light block onPress={props.goToLogin}>
<Text>Login</Text>
</Button>
<Button dark block bordered style={{marginTop: 10}} onPress={props.goToRegister}>
<Text>Register</Text>
</Button>
</View>
);
}
Splash.propTypes = {
goToLogin: PropTypes.func.isRequired,
goToRegister: PropTypes.func.isRequired
}
export default Splash;
I don't know your Router config, but your methods should be:
goToLogin = () => {
const { history } = this.props
history.push('/Login');
}
history will passed down via props of component inside Router's stack.
I'm using the new react-navigation library for a React Native application I'm building. I'm having an issue with passing down my ActionCreators from my Nav component down to its scenes.
I have an AppContainer that wraps the entire application.
import React, { Component } from 'react';
import { DrawerNavigator, addNavigationHelpers } from 'react-navigation';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
import DashboardContainer from './DashboardContainer';
import CustomersContainer from './CustomersContainer';
const ApplicationNavigation = DrawerNavigator({
Dashboard: { screen: DashboardContainer },
Customers: { screen: CustomersContainer },
});
class AppContainer extends Component {
render() {
return (
<ApplicationNavigation />
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(() => { return {} }, mapDispatchToProps)(AppContainer);
Here is the CustomerContainer:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
export default class CustomerContainer extends Component {
btnPressed() {
this.props.listCustomers()
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
Now I'm trying to call an action within my CustomerContainer this.props.listCustomers(). The problem is the ActionCreator props aren't being passed down to the screens. I've tried doing adding the screenProps prop to the ApplicationNavigation component:
But for some reason when I do this my app doesn't display any screens its just blank with no errors.
UPDATE
So I updated my CustomerContainer file:
import React, {Component} from 'react';
import {View, Text, Button} from 'react-native';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
console.log(this.props.listCompanyCustomers())
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}
function mapStateToProps(state) {
return {
companyCustomers: state.companyCustomers
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(CustomerContainer);
This now works; however this feels like the incorrect way to go about this.
What redux connect basically does is:
Wrap your component
Declare contextProps to get access to dispatch
pass the dispatch to your component props.
If you pass the connect mapDispatchToProps, then it creates the mapping of the methods to dispatch.
So if you connect you AppContainer, its children won't get these dispatch methods, unless AppContainer passes them to its children (but this what connect comes to prevent).
So to sum up, you should connect any component that needs to use dispatch, otherwise it won't get it.
If you don't want to copy paste the mapDispatchToProps, you can just delete it and use this.props.dispatch instead:
import { ActionCreators } from '../actions';
class CustomerContainer extends Component {
btnPressed() {
this.props.dispatch(ActionCreators.listCompanyCustomers());
}
render () {
return (
<View style={{marginTop: 40}}><Text>Customer</Text>
<Button onPress={() => this.btnPressed()} title="Press Me!" />
</View>
);
}
}