i'm using a Navigator component and want to pass data from a component to a other.
here is some code.
renderScene(route, navigator) {
var routeId = route.id;
if (routeId === 'SplashPage') {
return (
<SplashPage
navigator={navigator} />
);
}
if (routeId === 'Login') {
return (
<Login
navigator={navigator} />
);
}
if (routeId === 'Home') {
return (
<Home
navigator={navigator} />
);
}
....
I want to pass data from login to home when i click on a button for example
this.props.navigator.replace({
id: 'Home',
passProps: {
currentUser: this.user,
}
})
i would like to get the currentUser in the Home Component. I've tried some code that i found but nothing seem to work.
This is whant i want to do :
class Home extends React.Component {
constructor(props){
super(props);
this.currentUser = ????????
}
If anyone can help me with this i would be grateful.
Thanks
You can set up your renderScene method like this:
renderScene={(route, navigator) => {
return React.createElement(route.component, { ...this.props, ...route.passProps, navigator, route } );
}}
And use it like this:
this.props.navigator.replace({
component: Home,
passProps: {
currentUser: this.user,
}
})
And in Home, you can access currentUser like this:
<Text>{ this.props.currentUser }</Text>
Check out this thread for a more detailed example, but that should work for you.
Related
I'm struggling to make Navigator object visible in List Component.
Here the code explained: as you can see in RootDrawer, I have Concept component. It simply shows a list of items based on a id passed in param.
Each item points to another Concept with another id, but I get
undefined is not an object (evaluating 'navigation.navigate')
when I press on that <RippleButton> with onPress={() => navigation.navigate('Concept',{id:12}). The problem here I'm not passing the Navigation object correctly. How can I solve?
main Navigator drawer
const RootDrawer = DrawerNavigator(
{
Home: {
screen: StackNavigator({
Home: { screen: Home }
})
},
Search: {
screen: StackNavigator({
Cerca: { screen: Search },
Concept: { screen: Concept },
})
}
}
);
Concept component
export default class Concept extends Component {
loading = true
static navigationOptions = ({ navigation,state }) => ({
headerTitle: "",
title: `${navigation.state.params.title}` || "",
})
constructor(props) {
super(props);
}
async componentDidMount(){
}
render() {
const { params } = this.props.navigation.state;
const id = params ? params.id : null;
const { t, i18n, navigation } = this.props;
const Concept = DB.get(id)
return (
<View>
<ScrollView>
<List data={Concept.array|| []} title={"MyTile"} navigation={navigation} />
</ScrollView>
</View>
);
}
}
List Component
class List extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
const { navigation } = this.props;
}
_renderItem = (item,navigation) => (
<RippleButton
id={item.id}
onPress={() => navigation.navigate('Concept', { id: 12, otherParam: 'anything you want here'})}> //this line throws the error
<Text>{item.Term}</Text>
</RippleButton>
)
render() {
const { navigation } = this.props;
return (
<View>
<FlatList
data={this.props.data}
renderItem={({item}) => this._renderItem(item, navigation)}
/>
</View>)
}
}
Instead of passing the navigation prop, you can try using the withNavigation HOC.
Where your List Component is defined:
import { withNavigation } from 'react-navigation`
....
export default withNavigation(List)
Now the List component will have access to the navigation prop
I am new in react native and looking if someone could direct me in detail how to pass parameters to a child tab.
I researched already and found that it could be done using screenprops, however none of those gave me a clear understanding on how to use it to pass the parameters. A clean sample code could be beneficial.
It is quite easy you have not look around enough there are lots of packages, I recommend you to use following package, and take a look at following example. Next time research information that you need before you ask something.
import React, { Component } from 'react';
import { TabView, TabBar, SceneMap } from 'react-native-tab-view';
import SceneA from './SceneA';
import SceneB from './SceneB';
class Layout extends Component {
constructor(props) {
super(props);
this.state = {
index: 0,
routes: [
{ key: 'active', title: 'Scene A' },
{ key: 'inactive', title: 'Scene B' },
],
};
this.renderScene = this.renderScene.bind(this);
this.renderLabel = this.renderLabel.bind(this);
this.onTabChange = this.onTabChange.bind(this);
}
onTabChange(index) {
this.setState({ index });
}
// Here you can send props to different tab components
renderScene({ route }) {
if (!route.key) return null;
if (route.key === 'active') {
return <SceneA type="active" />; // SceneA specific props here
}
if (route.key === 'inactive') {
return <SceneB type="inactive" />;
}
}
renderLabel({ route }, props) {
const { index } = this.state;
const selected = route.key === props.navigationState.routes[index].key;
return (
<View>
<Text>
{route.title.toUpperCase()}
</Text>
</View>
);
}
renderTab() {
return (
<TabView
navigationState={this.state}
onIndexChange={this.onTabChange}
renderScene={this.renderScene}
renderTabBar={props => (
<TabBar
{...props}
renderLabel={e => this.renderLabel(e, props)}
/>
)}
/>
);
}
render() {
return (
<View>
{this.renderTab()}
</View>
);
}
}
export default Layout;
I am using a ListItem onPress to navigate to a different route using the code below.
onPress(item) {
this.props.navigator.push({
component: Areas,
passProps: {
new_id: item.new_id,
}
});
}
_renderItem(item) {
return (
<ListItem item={item} onPress={ () => this.onPress(item) }/>
);
}
However, the this.props.new_id is undefined in the next component.
export default class areas extends Component {
constructor(props) {
super(props);
console.log(" UUUU ");
console.log(this.props.new_id);
}
render(){
return (
<Text style={styles.liText}>AAA {this.props.new_id} BBB</Text>
);
}
AppRegistry.registerComponent('areas', () => areas);
Is there anything I am doing incorrectly?
Actually, I found the answer. I looked in renderScene which was not passing the props properly.
I fixed it in the following way:
Initial:
return React.createElement(route.component, { navigator });
To:
return React.createElement(route.component, { ...this.props, ...route.passProps, route, navigator } )
This seems the pass the props.
So, I have a simple button (TouchableHighlight) calling the following function:
showMovie() {
this.props.navigator.push({
name: 'MovieScreen',
index: 1,
movie: "terminator"
});
}
It works as expected, pushing the MovieScreen scene defined in a different file.
In the MovieScreen constructor I have:
constructor(props) {
super(props);
console.log(this.props.movie);
}
All I get is "undefined".
I tried with: console.log(this.props.passProps.movie); => undefined.
I tried putting the "movie" parameter in a passProps object => undefined.
I can't seem to pass parameters to a scene. If I print this.props I can't find anywhere the "movie" variable, but this.props is there and it contains the navigator object and everything.
Judging from the examples around the web, I'm doing exactly what thousands of people do, with the difference that mine doesn't work.
What I'm doing wrong?
More details as requested
This is how my app is composed:
index.android.js
HomepageScreen.js
MovieScreen.js
index.android.js
class MovieApp extends Component {
render() {
return (
<Navigator
initialRoute={{ name: 'HomepageScreen', title: 'My Initial Scene', index: 0 }}
renderScene={ this.renderScene }
/>
);
}
renderScene(route, navigator) {
if (route.name == 'HomepageScreen') {
return <HomepageScreen navigator={navigator} />
}
if (route.name == 'MovieScreen') {
return <MovieScreen navigator={navigator} />
}
}
}
HomepageScreen.js
export default class HomepageScreen extends Component {
constructor(props) {
super(props);
var navigator = this.props.navigator;
render() {
return(
<TouchableNativeFeedback onPress={this.showMovie.bind(this)}>
<View style={Style.movieButton}>
<Text style={Style.textStyle1}>Asd</Text>
</View>
</TouchableNativeFeedback>
);
}
showMovie() {
this.props.navigator.push({
name: 'MovieScreen',
index: 1,
movie: "terminator"
});
}
}
MovieScreen.js
export default class MovieScreen extends Component {
constructor(props) {
super(props);
console.log(this.props.movie);
}
.....
Try this:
renderScene(route, navigator) {
if (route.name == 'HomepageScreen') {
return <HomepageScreen navigator={navigator} {...route.passProps} />
}
if (route.name == 'MovieScreen') {
return <MovieScreen navigator={navigator} {...route.passProps} />
}
}
And passing the props like this:
this.props.navigator.push({
name: 'MovieScreen',
index: 1,
passProps: {
movie: "terminator"
}
});
I've seen a few examples online using Navigator.NavigationBar. It looks handy but I don't know how to use it. Are there docs anywhere?
Officially there is no guide Navigator.Navigation Bar. But looking on the internet you can find examples of how it works. Below is an example that I used for one of my projects.
var PageOne = require('./pageone'),
PageTwo = require('./pagetwo');
var NavigationBarRouteMapper = {
LeftButton: function( route, navigator, index, navState ){
return(
<Text>{ route.leftButton }</Text>
)
},
Title: function( route, navigator, index, navState ){
return(
<Text>{ route.title }</Text>
)
},
RightButton: function( route, navigator, index, navState ){
return(
<Text>{ route.rightButton }</Text>
)
}
}
var App = React.createClass({
renderScene: function( route, nav ) {
switch (route.id) {
case 'PageOne':
return <PageOne navigator={ nav } title={ "PageOne" } />
case 'PageTwo':
return <PageTwo navigator={ nav } leftButton={ "Back" } title={ "PageTwo" } />;
}
},
render: function() {
return (
<Navigator
initialRoute={{ id: 'PageOne', title: 'PageOne' }}
renderScene={ this.renderScene }
configureScene={( route ) => {
if ( route.sceneConfig ) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FloatFromRight;
}}
navigationBar={
<Navigator.NavigationBar
routeMapper={ NavigationBarRouteMapper }
/>
}
/>
);
},
});
Updates on 2017: Official documentation of React Native recommend using react-navigation library.
Setup variable:
import {
StackNavigator,
} from 'react-navigation';
const App = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
});
Example:
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to Jane's profile"
onPress={() =>
navigate('Profile', { name: 'Jane' })
}
/>
);
}
}
Read the official documentation for detailed information.
I would also add to checkout the UI Explorer in the examples that show how to use it. UIExplorer Navigator -
EDIT: React native has done a good job updating their docs. Here is the documentation to the navigator: navigator docs
UPDATE: Do your self a favor and use something like react-navigation. Those links will be broken because of MANY updates to RN.