【问题标题】:Passing data between React Native screens (From Screen A to Screen B to Screen C)在 React Native 屏幕之间传递数据(从屏幕 A 到屏幕 B 到屏幕 C)
【发布时间】:2020-08-16 17:38:18
【问题描述】:

考虑以下场景。 基本上我们有一个 MaterialTopTabNavigator 嵌套在 StackNavigator 中。

如何将我的数据从函数一直传递到MaterialTopTabNavigator。注意MaterialTopTabNavigator要先经过StackNavigator

file1.js

const[test,setTest] = useState('testing');
function moveToResults(){
    navigation.navigate('Results', test)
}

这里我们有一个简单的函数,它使应用导航到不同的屏幕并传递test 的状态。当moveToResults() 被调用时,我们会:

file2.js // 注意 PostFun 是 StackNavigator 的主页。

const Tab = createMaterialTopTabNavigator();

function PostFun({navigation}) {
  return (

         <Tab.Navigator 
            initialRouteName="Feed"
            activeColor="#e91e63"
            tabBarOptions={{
                labelStyle: {fontSize:12, color:"#faa19b"},
                tabStyle: {height:65, justifyContent: "flex-end"},
            }}
            style={styles.header}>
                <Tab.Screen name="Activity" component={FindFunActivity} />
                <Tab.Screen name="Event" component={FindFunEvent} />
        </Tab.Navigator>

  );
}

File2.js 是 `MaterialTopTabNavigator 的开头,您可以看到此导航有两个顶部选项卡(Activity 和 Event)。

其中一个选项卡可能看起来像这样,这是我需要显示变量的地方:

file3.js

const FindFunEvent = (navigation) =>{
return(
<View>
    <Text>{navigation.getParam()}</Text>
</View>
)

}

问题

如何让我的test 变量显示在FindFunEvent 组件中?

这比什么都难解释,如果你愿意,这里是视觉效果。

Here is the link to a short video that goes over the issue

【问题讨论】:

  • getParam 在 v4 中工作。由于您使用的是 v5,因此您应该使用 this.props.route.params
  • @SDushan 感谢您的帮助,为了更好地理解,您会这样做:this.navigation.route.params?我做对了吗?
  • 只是route.params。检查这个 - reactnavigation.org/docs/params
  • @SDushan 什么也没发生,我实际上得到了一个 route var missing 错误。问题是变量必须经过两次导航才能到达最终显示位置。
  • 两次导航是什么意思?

标签: reactjs react-native parameter-passing react-navigation


【解决方案1】:

你可以得到这个工作,将值作为组件的 prop 传递:

file1.js

const[test, setTest] = useState('testing');

function moveToResults(){
    navigation.navigate('Results', { test: test })
}

file2.js

const Tab = createMaterialTopTabNavigator();

function PostFun({ route, navigation }) {
  const { test } = route.params;

  return (
        <Tab.Navigator 
            initialRouteName="Feed"
            activeColor="#e91e63"
            tabBarOptions={{
                labelStyle: {fontSize:12, color:"#faa19b"},
                tabStyle: {height:65, justifyContent: "flex-end"},
            }}
            style={styles.header}
        >
          <Tab.Screen name="Activity">
              { (props) => <FindFunActivity {...props} myProp='test'  /> }
          </Tab.Screen>

          <Tab.Screen name="Event" component={() => <FindFunEvent test={test} />} />
        </Tab.Navigator>

  );
}

file3.js

const FindFunEvent = ({ test }) => {
  return(
    <View>
      <Text>{ test }</Text>
    </View>
  )
}

类似的例子可以在这里查看: https://snack.expo.io/UDHVnSUwK

【讨论】:

  • 我知道你在做什么。谢谢你的帮助。当我尝试显示以下内容时收到此警告:看起来您正在为屏幕“事件”的“组件”道具传递内联函数(例如,组件={()=> })。传递内联函数将导致组件状态在重新渲染时丢失并导致性能问题,因为它在每次渲染时都重新创建。您可以将函数作为子函数传递给“屏幕”以实现所需的行为。
  • @IllllIl 编辑了答案(见第 17 行 - file2.js)。使用这种新方式(屏幕作为子标签),您可以隐藏警告并实现您的目标!如果需要,我更新了snack.expo 以获得演示。
  • 非常感谢您的帮助。即使按照您在 file2.js 中所做的更改,警告似乎仍然存在。我认为问题警告标志位于我们具有内联功能的屏幕事件中。
  • 不客气!关于警告,我认为是的,但使用内联函数是将道具传递给 Tab.Screen 的常用方法。这个警告对我来说没有意义。无论如何,如果你得到这个工作,谢谢你的要求!
  • 如果您有时间并且知道发生了什么,我刚刚遇到了另一个问题:stackoverflow.com/questions/61630313/…
【解决方案2】:

假设您想要导航并将您在屏幕 A 中获得的值传递到屏幕 B 和屏幕 C。 你可以这样做

屏幕A

this.props.navigation.navigate('ScreenB',
   {value: 'hi', });
}

屏幕 B

this.props.navigation.navigate('ScreenC',
    this.props.route.params.value);
}

屏幕C

 this.props.route.params.value

【讨论】:

  • 感谢@James 的帮助!如果我想去屏幕 C 怎么办?通过屏幕 C,我的意思是变量必须从 A -> B -> C. 它不能从 A-> C.
  • @IllllIl 没问题!我相应地编辑了我的答案。您将能够访问 A 和 B 和 C 中的值。
  • 您会对 file2.js 进行哪些更改以接收该数据并将其传递到下一个屏幕? file2.js 基本上是其他两个屏幕之间的中间点,它必须接收和传递。希望我说得通。
  • @IllllIl 哦,我明白了,您的 file2.js 是导航路由文件。这似乎是一个糟糕的架构,因为我认为没有办法在导航中存储数据。您的导航组件应该严格地仅用于导航组件而不是存储数据。我能问一下你为什么要将它存储在导航器中吗?
  • 我不确定你是否有机会点击链接并观看简短的 GIF,但基本上我只关心能够在 file3.js 中显示数据 但不知何故,我认为它必须通过 file2.js。如果有办法绕过 file2.js 我很乐意做一些,但我不确定是否有。
【解决方案3】:

一个简单的方法是使用global.data。当您使用全局变量时,您可以在应用程序中的任何位置使用它。但这并不理想,因为在编程中使用全局并不是最佳实践。我不完全确定您尝试做的事情是否可行,如果不是,您可以求助于使用 global.

【讨论】:

  • 感谢您的建议。我希望避免使用全局变量,因为您认为它们不是“最佳实践”。
猜你喜欢
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多