在 React Native 中的页面之间传递数据
Posted
技术标签:
【中文标题】在 React Native 中的页面之间传递数据【英文标题】:Pass Data between Pages in React native 【发布时间】:2018-10-10 10:08:45 【问题描述】:我刚接触原生反应,我一直在追随。
我正在使用下面的代码执行导航(单击警报视图按钮时)。
const navigation = this.props.navigation;
…
.
.
text: 'Done', onPress:() =>
navigate.push(HomeScreen);
如何在 React Native 中将数据传递到另一个页面?我可以声明参数全局并分配给它吗?
执行此操作的正确方法是什么?我该怎么做?
【问题讨论】:
你在用react-navigation
吗?
【参考方案1】:
注意
这个答案是为
react-navigation: "3.3.0"
写的。由于有更新的版本可用,这可能会带来变化,您应该确保检查实际的documentation。
在react-navigation
中的页面之间传递数据相当简单。文档here
为了完整起见,让我们创建一个小应用程序,允许我们从一个屏幕导航到另一个屏幕之间传递值。在这个例子中,我们将只传递字符串,但也可以传递数字、对象和数组。
App.js
import React, Component from 'react';
import AppContainer from './MainNavigation';
export default class App extends React.Component
render()
return (
<AppContainer />
)
MainNavigation.js
import Screen1 from './Screen1';
import Screen2 from './Screen2';
import createStackNavigator, createAppContainer from 'react-navigation';
const screens =
Screen1:
screen: Screen1
,
Screen2:
screen: Screen2
const config =
headerMode: 'none',
initialRouteName: 'Screen1'
const MainNavigator = createStackNavigator(screens,config);
export default createAppContainer(MainNavigator);
Screen1.js
和 Screen2.js
import React, Component from 'react';
import View, StyleSheet, Text, Button from 'react-native';
export default class Screen extends React.Component
render()
return (
<View style=styles.container>
</View>
)
const styles = StyleSheet.create(
container:
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
);
这里有 4 个文件。我们将导入MainNavigation.js
的App.js
。 MainNavigation.js
设置了一个带有两个屏幕的StackNavigator
,Screen1.js
和Screen2.js
。 Screen1
已设置为我们的StackNavigator
的初始屏幕。
在屏幕之间导航
我们可以通过使用从Screen1
导航到Screen2
this.props.navigation.navigate('Screen2');
我们可以通过使用从Screen2
回到Screen1
this.props.navigation.goBack();
所以Screen1
中的代码变成了
export default class Screen extends React.Component
render()
return (
<View style=styles.container>
<Button title='Go to screen 2' onPress=() => this.props.navigation.navigate('Screen2') />
</View>
)
Screen2
中的代码变为:
export default class Screen extends React.Component
render()
return (
<View style=styles.container>
<Button title='Go back' onPress=() => this.props.navigation.goBack() />
</View>
)
现在我们可以在Screen1
和Screen2
之间导航
将值从Screen1
发送到Screen2
要在Screen1
和Screen2
之间发送一个值,涉及两个步骤。首先我们必须发送它,其次我们必须捕获它。
我们可以通过将值作为第二个参数传递来发送它。注意文本值是如何包含在对象中的。
this.props.navigation.navigate('Screen2', text: 'Hello from Screen 1' );
我们可以通过以下操作在Screen2
中捕获它,getParams
中的第一个值是key
,第二个值是默认值。
const text = this.props.navigation.getParams('text','nothing sent');
所以Screen1
现在变成了
export default class Screen extends React.Component
render()
return (
<View style=styles.container>
<Button
title='Go to screen 2'
onPress=() => this.props.navigation.navigate('Screen2',
text: 'Hello from screen 1'
) />
</View>
)
Screen2
中的代码变为:
export default class Screen extends React.Component
render()
const text = this.props.navigation.getParam('text', 'nothing sent')
return (
<View style=styles.container>
<Text>text</Text>
<Button
title='Go back'
onPress=() => this.props.navigation.goBack() />
</View>
)
将值从Screen2
发送回Screen1
我发现将值从Screen2
发送到Screen1
的最简单方法是从Screen1
向Screen2
传递一个函数,该函数将使用您想要的值更新Screen1
中的状态发送
所以我们可以更新Screen1
使其看起来像这样。首先我们在 state 中设置一个初始值。然后我们创建一个更新状态的函数。然后我们将该函数作为参数传递。我们将在Text
组件中显示来自Screen2
的捕获值。
export default class Screen1 extends React.Component
state =
value: ''
receivedValue = (value) =>
this.setState(value)
render()
return (
<View style=styles.container>
<Button
title='Go to screen 2'
onPress=() => this.props.navigation.navigate('Screen2',
text: 'Hello from Screen 1',
receivedValue: this.receivedValue
) />
<Text>this.state.value</Text>
</View>
)
请注意,我们传递函数 receivedValue
的方式与之前传递 text
的方式相同。
现在我们必须捕获Screen2
中的值,并且我们以与之前非常相似的方式来执行此操作。我们使用getParam
来获取值,记住设置我们的默认值。然后当我们按下 Go back 按钮时,我们更新它以首先调用receivedValue
函数,并传入我们想要发回的文本。
export default class Screen2 extends React.Component
render ()
const text = this.props.navigation.getParam('text', 'nothing sent');
const receivedValue = this.props.navigation.getParam('receivedValue', () => );
return (
<View style=styles.container>
<Button
title='Go back'
onPress=() =>
receivedValue('Hello from screen 2')
this.props.navigation.goBack()
/>
<Text>text</Text>
</View>
);
使用getParam
的替代方案
可以不使用getParam
方法,而是直接访问这些值。如果我们这样做,我们将无法设置默认值。然而它是可以做到的。
在Screen2
中,我们可以执行以下操作:
const text = this.props.navigation.state.params.text;
const receivedValue = this.props.navigation.state.params.receivedValue;
在生命周期事件中捕获值(Screen1
到 Screen2
)
react-navigation
允许您使用生命周期事件捕获值。我们有几种方法可以做到这一点。我们可以使用NavigationEvents
,也可以使用componentDidMount
中设置的监听器
这里是如何使用NavigationEvents
进行设置
import React, Component from 'react';
import View, StyleSheet, Text from 'react-native';
import NavigationEvents from 'react-navigation'; // you must import this
export default class Screen2 extends React.Component
state =
text: 'nothing passed'
willFocusAction = (payload) =>
let params = payload.state.params;
if (params && params.value)
this.setState(value: params.value);
render()
return (
<View style=styles.container>
<NavigationEvents
onWillFocus=this.willFocusAction
/>
<Text>Screen 2</Text>
<Text>this.state.text</Text>
</View>
)
这是使用componentDidMount
中的侦听器的方法
export default class Screen2 extends React.Component
componentDidMount ()
// we add the listener here
this.willFocusSubscription = this.props.navigation.addListener('willFocus', this.willFocusAction);
componentWillUmount ()
// we remove the listener here
this.willFocusSubscription.remove()
state =
text: 'nothing passed'
willFocusAction = (payload) =>
let params = payload.state.params;
if (params && params.value)
this.setState(value: params.value);
render()
return (
<View style=styles.container>
<Text>Screen 2</Text>
<Text>this.state.text</Text>
</View>
)
通过组件传递导航
在上面的示例中,我们在屏幕之间传递值。有时我们在屏幕上有一个组件,我们可能想从中导航。只要该组件在作为导航器一部分的屏幕中使用,我们就可以做到。
如果我们从初始模板开始构建两个按钮。一个是功能组件,另一个是 React 组件。
MyButton.js
// this is a functional component
import React, Component from 'react';
import View, StyleSheet, Text, TouchableOpacity from 'react-native';
export const MyButton = (navigation, value, title) =>
return (
<TouchableOpacity onPress=() => navigation.navigate('Screen2', value )>
<View style=styles.buttonStyle>
<Text>title</Text>
</View>
</TouchableOpacity>
)
const styles = StyleSheet.create(
buttonStyle:
width: 200,
height: 60,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red'
);
MyOtherButton.js
// this is a React component
import React, Component from 'react';
import View, StyleSheet, Text, TouchableOpacity from 'react-native';
export default class MyOtherButton extends React.Component
render()
const navigation, value, title = this.props;
return (
<TouchableOpacity onPress=() => navigation.navigate('Screen2', value )>
<View style=styles.buttonStyle>
<Text>title</Text>
</View>
</TouchableOpacity>
)
const styles = StyleSheet.create(
buttonStyle:
width: 200,
height: 60,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'yellow'
);
无论组件的类型如何,请注意导航是一个道具。我们必须将导航传递给组件,否则它将无法工作。
Screen1.js
import React, Component from 'react';
import View, StyleSheet, Text, Button from 'react-native';
import MyButton from './MyButton';
import MyOtherButton from './MyOtherButton';
export default class Screen1 extends React.Component
render()
return (
<View style=styles.container>
<Text>Screen 1</Text>
<MyButton
title='Press my button'
navigation=this.props.navigation
value='this is a string passed using MyButton'
/>
<MyOtherButton
title='Press my other button'
navigation=this.props.navigation
value='this is a string passed using MyOtherButton'
/>
</View>
)
const styles = StyleSheet.create(
container:
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
);
注意Screen1.js
,因为它包含在 StackNavigator 中,它可以访问this.props.navigation
。我们可以将它作为道具传递给我们的组件。只要我们在组件中使用它,我们就应该能够使用组件自己的功能进行导航。
<MyButton
title='Press my button'
navigation=this.props.navigation // pass the navigation here
value='this is a string passed using MyButton'
/>
小吃
这里是点心for passing params。 这里是点心for passing params and capturing in lifecycle events。 这是点心passing navigation to components【讨论】:
有没有办法在不触发导航的情况下将值从 screen1 传递到 screen2? 有很多不同的方法,这真的取决于你的应用程序设置。最简单的可能是使用事件发射器或 AsyncStorage,更多涉及的是使用 redux 设置。我建议将您的情况写成一个新问题,以便您可以清楚地表达您需要做的所有事情,因为 SO 上的 cmets 并不允许进行详细的讨论。一方面,这里的代码格式不好;其次,你被限制在 600 个字符以内,所以很难充分表达自己。 感谢您的详细回答,我现在对导航 getParam 有了更多了解))) 如何从平面列表中传递对象?【参考方案2】:1) 在主屏幕上:-
初始化:-
constructor(props)
super(props);
this.navigate = this.props.navigation.navigate;
发送:-
this.navigate("DetailScreen",
name: "Detail Screen",
about:"This is Details Screen Page"
);
2) 在详细屏幕上:-
初始化:-
constructor(props)
super(props);
this.params = this.props.navigation.state.params;
检索数据:-
console.log(this.params.name);
console.log(this.params.about);
【讨论】:
如果您在任何元素中显示,您也会显示为const navigate = this.props.navigation;
…
.
.
text: 'Done', onPress:() =>
navigate('homeScreen',...params);
你可以得到像这样的参数
const params = this.props.navigation.state
【讨论】:
【参考方案4】:HomeScreen.js
this.props.navigation.navigate('Screen2', user_name: 'aaa',room_id:'100' );
Screen2.js
const params = this.props.route.params;
user_name = params.user_name;
room_id = params.room_id
【讨论】:
如何从平面列表中传递对象?【参考方案5】:您可以使用react-navigation 轻松发送和接收您的参数,如下所示
发送参数:
text: 'Done',
onPress: () =>
this.props.navigation.navigate(
HomeScreen,
param1: 'value1', param2: 'value2'
);
获取参数在HomeScreen
:
const navigation = this.props;
var param1 = navigation.getParam('param1', 'NO-VALUE');
var param2 = navigation.getParam('param2', 'NO-VALUE');
'NO-VALUE'
是默认值,如果没有所需的参数
【讨论】:
【参考方案6】:我假设您正在使用 react-navigation。因此,在 react-navigation 中,我们可以分两部分传递数据:
通过将参数放在对象中作为 navigation.navigate 函数的第二个参数,将参数传递给路由:
this.props.navigation.navigate('RouteName', /* params go here */ )
读取屏幕组件中的参数:
this.props.navigation.getParam(paramName, someDefaultValue)
警报按钮
<Button
title="Alert View"
onPress=() =>
this.props.navigation.navigate('alerts',
itemId: 86,
otherParam: 'anything you want here',
);
/>
屏幕:
const itemId = navigation.getParam('itemId', 'NO-ID');
const otherParam = navigation.getParam('otherParam', 'some default value')
【讨论】:
【参考方案7】:屏幕 1:
<Button title="Go Next"
onPress=() => navigation.navigate('SecondPage', paramKey: userName ) />
屏幕 2:
const SecondPage = (route) =>
....
....
<Text style=styles.textStyle>
Values passed from First page: route.params.paramKey
</Text>
....
....
【讨论】:
以上是关于在 React Native 中的页面之间传递数据的主要内容,如果未能解决你的问题,请参考以下文章
React-Native - 在Component和Class之间传递数据