【问题标题】:How can I make these components navigate to another screen in react?我怎样才能让这些组件导航到另一个屏幕做出反应?
【发布时间】:2020-11-29 21:26:44
【问题描述】:

我目前正在开发一个 react 项目,该项目有一个导航页面,其中包含导航到应用程序各个部分的小部件。但是,我不确定如何让他们导航到相应的屏幕。

编辑:

我添加了更多代码以更好地说明我正在尝试做的事情。

import React from 'react';
import {View, FlatList, Text, TouchableOpacity, Dimensions} from 'react-native';
import LinearGradientScreen from './linearGradientScreen';
import Feather from 'react-native-vector-icons/Feather';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Entypo from 'react-native-vector-icons/Entypo';
const CellComponent = (props) => {
  return (
    <TouchableOpacity
      onPress={() => props.navigation.navigate('tabNavigator')}
      style={{
        backgroundColor: props.item.color,
        height: (13 * Dimensions.get('window').height) / 100,
        width: 132,
        borderRadius: 5,
        shadowColor: 'rgba(52,2,2,1)',
        shadowOffset: {
          width: 3,
          height: 3,
        },
        elevation: 5,
        shadowOpacity: 1,
        shadowRadius: 0,
        margin: 20,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      {props.item.family === 'Feather' ? (
        <Feather
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons1' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'Entypo' ? (
        <Entypo
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons2' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'FontAwesome' ? (
        <FontAwesome
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      <Text
        style={{
          color: 'white',
          fontSize: 18 * Dimensions.get('window').fontScale,
        }}>
        {props.item.name}
      </Text>
    </TouchableOpacity>
  );
};
const HomeScreen = (props) => {
  return (
    <LinearGradientScreen>
      <View style={{alignItems: 'center', justifyContent: 'center'}}>
        <Text
          style={{
            marginTop: '20%',
            fontSize: 50 * Dimensions.get('window').fontScale,
            color: 'white',
            fontWeight: 'bold',
          }}>
          Home
        </Text>
        <Text
          style={{
            fontSize: 25 * Dimensions.get('window').fontScale,
            color: 'white',
            fontWeight: '400',
            marginBottom: '10%',
          }}>
          Select a service
        </Text>
        <FlatList
          numColumns={2}
          data={HomeScreenData}
          renderItem={({item}) => {
            return <CellComponent {...props} item={item} />;
          }}
        />
      </View>
    </LinearGradientScreen>
  );
};
const HomeScreenData = [
  {
    id: 1,
    name: 'AI Chat',
    icon: 'cpu',
    family: 'Feather',
    color: 'rgba(247,52,122,1)',
  },
  {
    id: 2,
    name: 'Live Chat',
    icon: 'wechat',
    family: 'FontAwesome',
    color: 'rgba(16,165,245,1)',
  },
  {
    id: 3,
    name: 'Resources',
    icon: 'file-document-outline',
    family: 'MaterialCommunityIcons',
    color: 'rgba(74,74,74,1)',
  },
  {
    id: 1,
    name: 'Client Connect',
    icon: 'gesture-swipe-horizontal',
    family: 'MaterialCommunityIcons1',
    color: 'rgba(237,41,57,1)',
  },
  {
    id: 1,
    name: 'DM',
    icon: 'message',
    family: 'Entypo',
    color: 'rgba(74,144,226,1)',
  },
  {
    id: 1,
    name: 'Profile',
    icon: 'tooltip-account',
    family: 'MaterialCommunityIcons2',
    color: 'rgba(144,19,254,1)',
  },
];
export default HomeScreen;

是否有类似导航:'AiScreen.js', 的内容,我可以使用它使其导航到正确的位置?

【问题讨论】:

  • 您的问题不是很清楚,请说明有多少屏幕以及您希望导航流程如何进行。还显示您到目前为止尝试过的代码
  • 抱歉给您带来了困惑。有 6 个屏幕,我希望每个小部件在按下时导航到相应的屏幕。例如,人工智能聊天将导航到人工智能屏幕
  • 我已经添加了整个问题。希望这能让事情更清楚
  • 没有路由器的证据 - 你需要实现一个路由器来实现你的目标。有几种。如果您想要一个交钥匙解决方案,请调查 nextjs - 否则 react-router 可能会为您工作。
  • 比较简单,可以使用reactnavigation.org/docs/navigating

标签: javascript android ios reactjs react-native


【解决方案1】:

每个 Stack.Screen 都应该收到道具“name”,以使其在“navigation.navigate("RouteName")”上可用。

来自文档https://reactnavigation.org/docs/navigating/

import * as React from 'react';
import { Button, View, Text } from 'react-native';
    
    function HomeScreen({ navigation }) {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Home Screen</Text>
          <Button
            title="Go to Details"
            onPress={() => navigation.navigate('Details')}
          />
        </View>
      );
    }
export default HomeScreen;

如果您像文档中那样命名您的路线

import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import DetailsScreen from "~/pages/Detail";
import HomeScreen from "~/pages/Home";

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator "initialRouteName="Home"  >
        <Stack.Screen name="Details" component={DetailsScreen} />
        <Stack.Screen name="Home" component={HomeScreen} />

      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

与您传递给 “name” props 的名称匹配的 组件上的“initialRouteName="Home" 方式相同

【讨论】:

  • 非常感谢您的回答,但是“您给 组件的名称”是什么意思?
  • 是关于每个 Stack.Screen 应接收的道具“名称”,以使其在“navigation.navigate(“RouteName”)”上可用。与您在 组件上具有与您传递给 的名称匹配的“initialRouteName="Home" 相同的方式
【解决方案2】:

输出:

这是一个例子,这里我已经实现了如何导航到 Ai 聊天屏幕,就像您可以创建其他屏幕,在 Stack Navigator 中定义它们并在其中导航。

import * as React from 'react';
import { Button, View, Text, FlatList } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';

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

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="AI Chat" component={AiChatScreen} />
        <Stack.Screen name="Resources" component={ResourcesScreen} />
        <Stack.Screen name="DM" component={DmScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
        <Stack.Screen name="Live Chat" component={LiveChatScreen} />
        <Stack.Screen name="Client Connect" component={ClientConnectScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

function LiveChatScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Live Chat Screen</Text>
    </View>
  );
}

function ResourcesScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Resources Screen</Text>
    </View>
  );
}

function ClientConnectScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Client Connect Screen</Text>
    </View>
  );
}

function DmScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>DM Screen</Text>
    </View>
  );
}

function ProfileScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Profile Screen</Text>
    </View>
  );
}

export default App;

修改了CellComponent,路由采用props.item.name

因此,您不必担心为每个屏幕输入路线名称。

const CellComponent = (props) => {
  return (
    <TouchableOpacity
      onPress={() => props.navigation.navigate(props.item.name)}
      style={{
        backgroundColor: props.item.color,
        height: (13 * Dimensions.get('window').height) / 100,
        width: 132,
        borderRadius: 5,
        shadowColor: 'rgba(52,2,2,1)',
        shadowOffset: {
          width: 3,
          height: 3,
        },
        elevation: 5,
        shadowOpacity: 1,
        shadowRadius: 0,
        margin: 20,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      {props.item.family === 'Feather' ? (
        <Feather
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons1' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'Entypo' ? (
        <Entypo
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons2' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'MaterialCommunityIcons' ? (
        <MaterialCommunityIcons
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      {props.item.family === 'FontAwesome' ? (
        <FontAwesome
          type={props.item.type}
          color={'rgba(255,255,255,1)'}
          name={props.item.icon}
          size={30}
        />
      ) : null}
      <Text
        style={{
          color: 'white',
          fontSize: 18 * Dimensions.get('window').fontScale,
        }}>
        {props.item.name}
      </Text>
    </TouchableOpacity>
  );
};

工作示例:Expo Snack

【讨论】:

  • 初始路由名称是否必须是用户遇到的第一个屏幕?因为我在主屏幕之前有一个登录屏幕,现在它出现问题了
  • 我已经更新了整个代码库,详细实现请到下面给出的 Expo Snack 链接。您可以在上传的抓屏中看到应用行为
  • 哦,好吧。这表示带有有效载荷 {"name": "AI Chat"} 的操作 'NAVIGATE' 没有被任何导航器处理。如果 ai chat 使用 AiScreen 的实际屏幕名称,我替换了所有实例。你知道这可能是什么原因吗?
  • 关于评论中的查询,我可能需要先看一下代码,然后再提出任何建议。
  • 我投了赞成票,但我的声誉很低,所以它没有出现:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-09
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
相关资源
最近更新 更多