Following are some options of passing data between screens
<SomeComponent style={{ color:'blue'}}, someProp={someData}></SomeComponent>
constructor(props) {
super(props);
aVar = this.props.someProp;
}
Local storage such as shared preferences or json storage can be used to store and retrieve data in multiple pages
Similar to local storage, databases can be used to imitate data communication between screens
Callbacks which can be passed as prop to a component can be used to transfer data to and fro
Navigator object which is received by implementing react-navigation-stack
and react-navigation
modulesis accessible as prop to each screen provided in the declaration of the stack navigator
This navigator object allows to access its state, which contains the data passed from the page/screen that initiates the navigation
Example provided below implements navigator and callback for passing data between screens
Check React Native Installation for installation related info
Use react-native init
command to create a new React Native project (here named NcScreenDataTransfer)
react-native init NcScreenDataTransfer
This creates a directory named NcScreenDataTransfer and initializes it as a react native application directory
This can be skipped in case an existing react native project is being integrated into
Since this example uses NavigationDrawer component, related packages have to be added
Go to project directory (here NcScreenDataTransfer)
cd NcScreenDataTransfer
Add react-navigation
react-navigation-drawer
&& react-navigation-stack
and associated dependencies to current project using yarn
yarn add react-navigation react-navigation-drawer react-navigation-stack \
react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-screens
or using npm
npm install react-navigation react-navigation-drawer react-navigation-stack \
react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-screens --save
After yarn add
command, cd into ios folder inside project directory
cd ios
Use pod command to install any required CocoaPods dependencies:
pod install
Following is code ofr App.js and UserPage.js
App.js contains ListPage
Component to display a list of users and allows to select a user whose data is passed to UserPage
Check inline comments
import React, { Component } from 'react';
import { StyleSheet, View, Button, TextInput, FlatList, Text, TouchableOpacity } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator} from 'react-navigation-stack';
import UserPage from './UserPage';
//List page which displays a list of users
export default class ListPage extends Component {
constructor(props) {
super(props);
// an array with data of users is declared as state
this.state = {
users: [
{key: 'Devin'},
{key: 'Dan'},
{key: 'Dominic'},
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John', number:''},
{key: 'Jillian', number: '373'},
{key: 'Jimmy'},
{key: 'Julie'},
]
};
}
static navigationOptions = {
title: 'UserList Page',
};
// receives updated value(number) for a key and updates users array
editCallback(key, value) {
var copy = [];
for(var i=0; i<this.state.users.length; i++) {
if(this.state.users[i].key == key) {
copy.push({key: key, number: value});
}
else {
copy.push(this.state.users[i]);
}
}
this.setState({
users: copy
});
};
// navigate to Userpage while passing data of a user along-with
// a callback function is also passed which receives updates done on Userpage
navigateToPage(item) {
const { navigate } = this.props.navigation;
navigate('UserPage', {
name: item.key,
number: item.number ? item.number + '': '',
// this has to be a lambda and cannot be replaced by 'this.editCallback'
// due to the use of 'this' keyword inside editCallback()
editCallback: (key, value) => this.editCallback(key, value)
})
}
// returns layout for each item of array
renderItem(item) {
var numberView = null;
if(item.number && item.number.length > 0) {
numberView = <Text style={styles.number}>{item.number}</Text>
}
return (
// button to navigate to the page of an item (user)
<TouchableOpacity style={styles.item} onPress={() => this.navigateToPage(item)}>
<Text>{item.key}</Text>
{numberView}
</TouchableOpacity>
);
}
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.users}
renderItem={({item}) => this.renderItem(item) }
/>
</View>
);
};
}
const App = createStackNavigator(
//list of pages/screens which can be navigated to
{
ListPage: { screen: ListPage },
UserPage: { screen: UserPage },
},
// initial page
{
initialRouteName: 'ListPage',
}
);
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
padding: 16,
},
input: {
width: 200,
height: 44,
padding: 10,
marginBottom: 10,
backgroundColor: '#DBDBD6',
},
item: {
backgroundColor: 'lightblue',
width: 200,
padding: 10,
margin: 2,
flex: 1,
flexDirection: 'row'
},
number: {
position : 'absolute',
right:20,
alignSelf: 'center'
}
});
export default createAppContainer(App);
UserPage
component allows to update number for a user which is sent through the callback provided to it, to ListPage
import React, { Component } from 'react';
import { StyleSheet, View, Text, TextInput } from 'react-native';
export default class UserPage extends Component {
static navigationOptions = {
title: 'User Page',
};
constructor(props) {
super(props);
// 'navigation' prop contains a 'state' with attribute 'params'
// which holds the data passed to 'navigate()' function of previous screen
this.state = {
data: this.props.navigation.state.params
};
}
render() {
const { name, number, editCallback } = this.state.data;
return (
<View style={styles.container}>
<Text> Page for </Text>
<Text style={styles.TextStyle}>
{name}
</Text>
// changes to TextInput invokes callback function to which the updated number is passed
<TextInput
value={number}
onChangeText={(numberEdit) => {
this.state.data.number = numberEdit;
this.setState({});
editCallback(name, numberEdit); }
}
placeholder={'Enter some number'}
style={styles.input}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
margin: 50,
alignItems: 'center',
justifyContent: 'center',
},
TextStyle: {
fontSize: 23,
textAlign: 'center',
color: '#f00',
},
input: {
backgroundColor: '#cff'
}
});
cd into project directory (here NcScreenDataTransfer)
cd NcScreenDataTransfer
Run metro server to serve js
react-native start
Go to project directory in another terminal tab
Enter following run command for Android:
react-native run-android
cd into project directory (here NcScreenDataTransfer)
cd NcScreenDataTransfer
Enter following command :
react-native run-ios
This might take some time
If the app shows error about metro server not configured (check Running an App in iOS), then run metro server in another tab:
react-native start
Reload the app
Re-run react-native run-ios
command if reloading doesn't work