在 React Native 中的页面之间传递数据 [英] Pass Data between Pages in React native

查看:52
本文介绍了在 React Native 中的页面之间传递数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始反应原生,我一直在关注.

Im new to react native and I'm stuck at following.

我正在使用下面的代码执行导航(当点击警报视图按钮时).

Im performing navigation (when clicked on alert view button) using the code below.

const {navigation} = this.props.navigation;
…
.
.
 { text: 'Done', onPress:() => {
              navigate.push(HomeScreen);}

如何在 React Native 中将数据传递给另一个页面?我可以声明全局参数并分配给它吗?

How can I pass data to another Page in React native? Can I declare the parameter global and just assign to it?

执行此操作的正确方法是什么,我将如何进行?

What would be the correct way of performing this and how would I go about it?

推荐答案

注意

此答案是为 react-navigation: "3.3.0" 编写的.由于有可用的更新版本,可能会带来更改,因此您应该确保查看实际的文档.>

Note

This answer was written for react-navigation: "3.3.0". As there are newer versions available, which could bring changes, you should make sure that you check with the actual documentation.

react-navigation 中的页面之间传递数据相当简单.它在文档这里

Passing data between pages in react-navigation is fairly straight forward. It is clearly explained in the documentation here

为了完整起见,让我们创建一个小应用程序,允许我们从一个屏幕导航到另一个屏幕之间传递值.在这个例子中,我们将只传递字符串,但也可以传递数字、对象和数组.

For completeness let's create a small app that allows us to navigate from one screen to another passing values between the screens. We will just be passing strings in this example but it would be possible to pass numbers, objects and arrays.

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.jsScreen2.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.jsApp.js.MainNavigation.js 设置了一个带有两个屏幕的 StackNavigatorScreen1.jsScreen2.js.Screen1 已被设置为我们的 StackNavigator 的初始屏幕.

Here we have 4 files. The App.js which we will import the MainNavigation.js. The MainNavigation.js sets up a StackNavigator with two screens, Screen1.js and Screen2.js. Screen1 has been set as the initial screen for our StackNavigator.

我们可以使用

this.props.navigation.navigate('Screen2');

我们可以使用

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>
    )
  }
}

现在我们可以在 Screen1Screen2

Now we can navigate between Screen1 and Screen2

要在Screen1Screen2 之间发送一个值,涉及两个步骤.首先我们必须发送它,其次我们必须捕获它.

To send a value between Screen1 and Screen2, two steps are involved. First we have to send it, secondly we have to capture it.

我们可以通过将其作为第二个参数传递来发送值.注意文本值是如何包含在对象中的.

We can send a value by passing it as a second parameter. Notice how the text value is contained in an object.

this.props.navigation.navigate('Screen2', {text: 'Hello from Screen 1' });

我们可以通过执行以下操作在Screen2中捕获它,getParams中的第一个值是key,第二个值是默认值价值.

And we can capture it in Screen2 by doing the following, the first value in getParams is the key the second value is the default value.

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 中的状态

Sending values from Screen2 back to Screen1

The easiest way I have discovered to send a value from Screen2 to Screen1 is to pass a function to Screen2 from Screen1 that will update the state in Screen1 with the value that you want to send

所以我们可以更新 Screen1 看起来像这样.首先我们在 state 中设置一个初始值.然后我们创建一个函数来更新状态.然后我们将该函数作为参数传递.我们将在 Text 组件中显示从 Screen2 捕获的值.

So we can update Screen1 to look like this. First we set an initial value in state. Then we create a function that will update the state. Then we pass that function as a parameter. We will display the captured value from Screen2 in a Text component.

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 的方式相同.

Notice that we are passing the function receivedValue in the same way that we passed the text earlier.

现在我们必须在 Screen2 中捕获值,我们以与之前非常相似的方式进行.我们使用 getParam 来获取值,记住设置我们的默认值.然后,当我们按下 返回 按钮时,我们更新它以首先调用 receivedValue 函数,传入我们想要发回的文本.

Now we have to capture the value in Screen2 and we do that in a very similar way that we did previously. We use getParam to get the value, remembering to set our default. Then when we press our Go back button we update it to call the receivedValue function first, passing in the text that we want to send back.

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 方法而是直接访问值.如果我们这样做,我们将无法设置默认值.然而这是可以做到的.

Alternatives to using getParam

It is possible to not use the getParam method and instead access the values directly. If we were to do that we would not have the option of setting a default value. However it can be done.

Screen2 中,我们可以执行以下操作:

In Screen2 we could have done the following:

const text = this.props.navigation.state.params.text;
const receivedValue = this.props.navigation.state.params.receivedValue;

在生命周期事件中捕获值(Screen1Screen2)

react-navigation 允许您使用生命周期事件捕获值.有几种方法可以做到这一点.我们可以使用 NavigationEvents 或者我们可以使用 componentDidMount

Capturing values in lifecycle events (Screen1 to Screen2)

react-navigation allows you to capture values using the lifecycle events. There are a couple of ways that we can do this. We could use NavigationEvents or we could use listeners set in the 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>
    )
  }
}

通过组件传递导航

在上面的例子中,我们已经将值从一个屏幕传递到另一个屏幕.有时我们在屏幕上有一个组件,我们可能想从中导航.只要组件在作为导航器一部分的屏幕中使用,我们就可以做到.

Passing navigation via components

In the above examples we have passed values from screen to screen. Sometimes we have a component on the screen and we may want to navigate from that. As long as the component is used within a screen that is part of a navigator then we can do it.

如果我们从初始模板开始构建两个按钮.一个是函数组件,另一个是 React 组件.

If we start from our initial template and construct two buttons. One will be a functional component the other a React component.

// 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'
  }
});

无论组件的类型如何,请注意导航是一个道具.我们必须将导航传递给组件,否则它将无法工作.

Regardless of the type of component, notice that navigation is a prop. We must pass navigation to the component otherwise it will not work.

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.我们可以将它作为道具传递给我们的组件.只要我们在组件中使用它,那么我们就应该能够使用组件自己的功能进行导航.

Notice in Screen1.js as it is contained in a StackNavigator it will have access to this.props.navigation. We can pass that through to our component as a prop. As long as we use that in our component then we should be able to navigate by using the components own functionality.

<MyButton 
  title={'Press my button'} 
  navigation={this.props.navigation} // pass the navigation here
  value={'this is a string passed using MyButton'} 
/>

零食

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆