将主屏幕拆分为多个组件后,出现导航。导航类型错误

问题描述 投票:0回答:1

我正在使用两个屏幕(主屏幕和详细信息屏幕)运行我的应用程序,所有程序都在工作,但是代码很长,所以我试图将所有内容拆分为可重用的组件,从而导致navigation.navigation类型错误由于某种原因。

我多次检查代码,一切对我来说都是很有意义的,这里是否缺少某些内容,如何解决此错误?

我是第一次使用React导航版本5。

这里是使用的代码示例:

MainScreen.js

import React from "react";
import { StyleSheet, Text, View, Image, FlatList } from "react-native";
import ArticleList from "../components/ArticleList";

function MainScreen() {
  return (
    <View style={{ flex: 1 }}>


      {/* show the data in a flatlist */}
      <ArticleList />

    </View>
  );
}
MainScreen.navigationOptions = () => {
  return {
    headerShown: false,
  };
};

export default MainScreen;

DetailScreen.js

import React from "react";
import { StyleSheet, Text, View, Dimensions, Image } from "react-native";
import { Feather } from "@expo/vector-icons";
import { SharedElement } from "react-native-shared-element";
import { TouchableOpacity, ScrollView } from "react-native-gesture-handler";
const DetailScreen = (props) => {
  const { width, height } = Dimensions.get("window");
  const { data } = props.route.params;
  return (
    <View style={styles.container}>
      <View>
        <SharedElement id={`item.${data.id}.photo`}>
          <Image
            resizeMode="cover"
            source={{ uri: data.image }}
            style={{
              width: 400,
              height: 300,
              borderBottomLeftRadius: 10,
              borderBottomRightRadius: 10,
            }}
          />
        </SharedElement>
        <View
          style={{
            flexDirection: "row",
            alignItems: "center",
            position: "absolute",
            bottom: 14,
            left: 10,
          }}
        >
          <SharedElement id={`item.${data.id}.profilePic`}>
            <Image
              resizeMode="cover"
              source={{ uri: data.profilePic }}
              style={{
                width: 60,
                height: 60,
                borderRadius: 10,
                marginRight: 14,
              }}
            />
          </SharedElement>
          <View
            style={{
              flex: 1,
              flexDirection: "row",
              alignItems: "center",
              justifyContent: "space-between",
            }}
          >
            <View>
              <SharedElement id={`item.${data.id}.username`}>
                <Text
                  style={{ color: "white", fontSize: 16, fontWeight: "bold" }}
                >
                  {data.username}
                </Text>
              </SharedElement>
              <SharedElement id={`item.${data.id}.readtime`}>
                <Text style={{ color: "white", fontSize: 14 }}>
                  {data.readtime}
                </Text>
              </SharedElement>
            </View>
            <TouchableOpacity>
              <Feather name="bookmark" size={30} color="white" />
            </TouchableOpacity>
          </View>
        </View>
      </View>
      <ScrollView style={{ paddingHorizontal: 10, paddingTop: 14 }}>
        <SharedElement
          id={`item.${data.id}.text`}
          style={{ width: width - 30, marginBottom: 14 }}
        >
          <Text style={{ fontSize: 22, fontWeight: "bold", lineHeight: 32 }}>
            {data.title}
          </Text>
        </SharedElement>
        <Text
          style={{
            fontSize: 14,
            lineHeight: 28,
            textAlign: "justify",
            opacity: 0.5,
          }}
        >
          Paragraph 1
        </Text>
        <Text
          style={{
            fontSize: 14,
            lineHeight: 28,
            textAlign: "justify",
            opacity: 0.5,
          }}
        >
          Paragraph 2
        </Text>
        <View
          style={{
            marginVertical: 25,
            paddingBottom: 20,
            flex: 1,
            flexDirection: "row",
            justifyContent: "space-between",
            alignItems: "center",
          }}
        >
          <TouchableOpacity
            style={{ flexDirection: "row", padding: 12, alignItems: "center" }}
          >
            <Feather name="heart" size={16} color="orange" />
            <Text style={{ marginHorizontal: 10 }}>3.4k Likes</Text>
          </TouchableOpacity>
        </View>
      </ScrollView>
      <View style={{ position: "absolute", top: 40, left: 10 }}>
        <TouchableOpacity onPress={() => props.navigation.goBack()}>
          <Feather name="arrow-left" size={24} color="white" />
        </TouchableOpacity>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});
export default DetailScreen;

ArticleList.js

import React from "react";
import {
  View,
  Text,
  StyleSheet,
  Image,
  Dimensions,
  FlatList,
} from "react-native";
import { SharedElement } from "react-native-shared-element";
import TouchableScale from "react-native-touchable-scale";
import { data } from "../data";

function ArticleList({ navigation }) {
  const { width, height } = Dimensions.get("window");
  return (
    <View>
      <FlatList
        horizontal
        showsHorizontalScrollIndicator={false}
        style={{ paddingHorizontal: 30 }}
        data={data}
        keyExtractor={(item) => item.id}
        renderItem={({ item }) => {
          return (
            <View>
              <View>
                <TouchableScale
                  activeScale={0.9}
                  tension={50}
                  friction={7}
                  useNativeDriver
                  onPress={() =>
                    navigation.navigate("DetailScreen", { data: item })
                  }
                >
                  {/* to show the horizental news list*/}
                  <SharedElement id={`item.${item.id}.photo`}>
                    <Image
                      source={{ uri: item.image }}
                      style={{
                        width: width - 100,
                        height: height - 350,
                        borderRadius: 14,
                        marginRight: 30,
                      }}
                    />
                  </SharedElement>
                  {/* to show the news titles inside the pictures*/}
                  <SharedElement
                    id={`item.${item.id}.text`}
                    style={{
                      width: width - 100,
                      position: "absolute",
                      bottom: 90,
                      left: 10,
                      paddingHorizontal: 10,
                    }}
                  >
                    <Text style={styles.blogTitle}>{item.title}</Text>
                  </SharedElement>
                  {/* to show the pictre of the author of the news article*/}
                  <View
                    style={{
                      flexDirection: "row",
                      alignItems: "center",
                      position: "absolute",
                      bottom: 20,
                      left: 20,
                    }}
                  >
                    <SharedElement id={`item.${item.id}.profilePic`}>
                      <Image
                        resizeMode="cover"
                        source={{ uri: item.profilePic }}
                        style={styles.blogProfilePic}
                      />
                    </SharedElement>
                  </View>
                  {/* to show the name of the author and read time of article*/}
                  <View>
                    <SharedElement id={`item.${item.id}.username`}>
                      <Text style={styles.blogUsername}>{item.username}</Text>
                    </SharedElement>
                    <SharedElement id={`item.${item.id}.readtime`}>
                      <Text style={styles.readtime}>{item.readtime}</Text>
                    </SharedElement>
                  </View>
                </TouchableScale>
              </View>
            </View>
          );
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  blogTitle: {
    color: "white",
    fontSize: 24,
    fontWeight: "bold",
    lineHeight: 28,
  },
  blogProfilePic: {
    height: 50,
    width: 50,
    borderRadius: 10,
    marginRight: 14,
  },
  blogUsername: {
    color: "white",
    fontSize: 16,
    fontWeight: "bold",
  },
  readtime: {
    fontSize: 14,
    color: "white",
  },
});

export default ArticleList;

App.js

import React from "react";
import "react-native-gesture-handler";
import { createSharedElementStackNavigator } from "react-navigation-shared-element";
import { NavigationContainer } from "@react-navigation/native";
import MainScreen from "./app/screens/MainScreen";
import DetailScreen from "./app/screens/DetailScreen";

const Stack = createSharedElementStackNavigator();

const App = ({ navigation }) => {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="MainScreen"
        screenOptions={{ headerShown: false }}
      >
        <Stack.Screen name="MainScreen" component={MainScreen} />
        <Stack.Screen
          name="DetailScreen"
          component={DetailScreen}
          options={(navigation) => ({
            headerBackTitleVisible: false,
            cardStyleInterpolator: ({ current: { progress } }) => {
              return {
                cardStyle: {
                  opacity: progress,
                },
              };
            },
          })}
          sharedElements={(route) => {
            const { data } = route.params;
            return [
              {
                id: `item.${data.id}.photo`,
                animation: "move",
                resize: "clip",
                align: "center-top",
              },
              {
                id: `item.${data.id}.text`,
                animation: "fade",
                resize: "clip",
                align: "left-center",
              },
              {
                id: `item.${data.id}.profilePic`,
                animation: "move",
                resize: "clip",
                align: "left-center",
              },
              {
                id: `item.${data.id}.username`,
                animation: "fade",
                resize: "clip",
                align: "left-center",
              },
              {
                id: `item.${data.id}.readtime`,
                animation: "fade",
                resize: "clip",
                align: "left-center",
              },
            ];
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};
export default App;

我为冗长的代码示例致歉,我试图保留与问题直接相关的所有内容。

reactjs react-native react-navigation
1个回答
0
投票
问题是您正在访问导航堆栈之外的导航。当您将平面列表移动到ArticleList时,其在导航之外,并且不会获得导航道具。您可以通过两种方式处理此问题。

  1. 您可以简单地从主屏幕通过导航

    功能MainScreen({导航}){返回({/ *在清单中显示数据* /});}

  2. 您可以使用useNavigation挂钩在导航之外访问导航。
© www.soinside.com 2019 - 2024. All rights reserved.