首页 文章

React Navigation - 如何在TabNavigator中的不同屏幕上传递数据?

提问于
浏览
1

我有一个TabNavigator,每个选项卡中都有一个StackNavigator . 在StackNavigator里面,我有屏幕 . 每个标签中的屏幕不会直接相互调用; TabNavigator在按下选项卡时处理屏幕更改 .

在第一个选项卡中,如果用户单击按钮,则会创建一些数据 . 如果用户然后导航到第二个选项卡,我想将此数据传递到第二个选项卡中的屏幕 .

这是代码的演示:

import React from 'react';
import { Button, Text, View } from 'react-native';
import {
  createBottomTabNavigator,
  createStackNavigator,
} from 'react-navigation';


class HomeScreen extends React.Component {
  doIt = () => {
    this.props.navigation.setParams({results: ['one', 'two']});   // <--- set data when user clicks button.
  }

  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        {/* other code from before here */}
        <Button
          title="Set Results"
          onPress={this.doIt}
        />
      </View>
    );
  }
}

class SettingsScreen extends React.Component {
  render() {

    console.log(this.props.navigation);  // <--- console out when user clicks on this tab

    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Settings</Text>
      </View>
    );
  }
}

const HomeStack = createStackNavigator({
  Home: HomeScreen,
});

const SettingsStack = createStackNavigator({
  Settings: SettingsScreen,
});

export default createBottomTabNavigator(
  {
    Home: HomeStack,
    Settings: SettingsStack,
  },
  {
  }
);

this.props.navigation.state.params 永远不会在第二个选项卡中获取数据 results . 甚至没有密钥,所以如果我尝试访问 this.props.navigation.state.params.results ,它将是未定义的 .

这很令人困惑,因为我认为 props.navigationpassed to all screens automatically .

如何通过TabNavigator将数据从一个屏幕传递到另一个屏幕,只使用反应导航?我已经看到了使用Redux的答案,但我不想导入另一个库,如果我想要的是在不同的反应导航器中屏幕上保持一些状态 .

3 回答

  • 0

    似乎 this.props.navigation.state.params 只能使用旧的一个参数?可能?试试这个:

    doIt = () => {
        this.props.navigation.setParams({results: 'one'});   // <--- set data when user clicks button.
      }
    
    
    console.log(this.props.navigation.state.params.results);
    
  • 0

    在跨不同选项卡传递数据时,设置道具不起作用 . 我甚至尝试过使用AsyncStorage,试图在不同的标签中保存和检索它们 .

    我最终使用Redux来保存我的状态,到目前为止一直运行良好 .

  • 2

    我遇到了类似的问题 . 我有一个多页面表单,客户端坚持要将每个步骤都包含在选项卡栏的选项卡中 . 我使用react navigation createMaterialTopTabNavigator 来创建导航器,但找不到在标签之间传递表单数据的简单方法 .

    我最终做的是使用react的Context API并将选项卡导航器包装在根表单容器中,该容器为导航器和内部路由提供上下文值 . 我是这样做的:

    根表单容器

    // MultiScreenForm.js
    imports...
    import MultiScreenFormNavigator from './MultiScreenFormNavigator'
    
    export const FormContext = React.createContext()
    
    class MultiScreenForm extends Component {
      constructor(props) {
        super(props)
        this.state = {
          // formDataHere
          formUpdaters: {
            onToggleOpIn: this.handleToggleOptIn // example updater method
            // other
          }
      }
      handleToggleOptIn = () => {
        // toggle opt in form data with this.setState
      }
    
      render() {
        return (
          <FormContext.Provider value={this.state}>
            <MultiScreenFormNavigator />
          </FormContext.Provider>
        )
      }
    }
    
    export default MultiScreenForm
    

    示例表单页面

    // ProfileForm.js
    imports...
    import { FormContext } from './MultiScreenForm'
    
    class ProfileForm extends Component {
      render() {
        // FormContext.Consumer uses function as child pattern
        return (
          <FormContext.Consumer>
            { (context) => (
                 // our form can now use anything that we pass through the context
                 // earlier, we passed the root form's state including an updater
                 <button onPress={context.formUpdaters.onToggleOptIn} />
                 // ...
              )
            }
          </FormContext.Consumer>
        )
      }
    }
    
    export default ProfileForm
    

    标签导航器

    // MultiScreenFormNavigator.js
    imports...
    import ProfileForm from './ProfileForm'
    import { createMaterialTopTabNavigator } from 'react-navigation'
    
    const MultiScreenFormNavigator = createMaterialTopTabNavigator(
      {
        Profile: ProfileForm,
        // AnotherForm: AnotherForm
      },
      // { navigator options here... }
    )
    
    export default MultiScreenFormNavigator
    

    然后,我们直接渲染MultiScreenForm而不是Tab键导航器 .

    这对我有用,但我觉得应该有一个更简单的方法来做到这一点 . 我希望读过这篇文章的人可以分享他们的方法 .

相关问题