Property 'category' does not exist on type 'Readonly<unknown>' and Property 'data' does not exist on type 'Readonly<unknown>'

677 Views Asked by At

I am trying to access the data from route.params sent from navigation screen, App is running fine but typescript conplain about my code "Property 'data' does not exist on type 'Readonly', Property 'category' does not exist on type 'Readonly'. if I console.log(route?.params?.category) & console.log(route?.params?.data) I will get the expected result. Here are my files.

types.tsx

import type { NativeStackScreenProps } from "@react-navigation/native-stack";

declare global {
  namespace ReactNavigation {
    interface RootParamList extends RootStackParamList {}
  }
}

export type RootStackParamList = {
  HomeScreen: undefined;
  CategoryDetailScreen: { category: string };
  SeachDetailScreen: { data: string[] };
};

export type RootStackScreenProps<Screen extends keyof RootStackParamList> =
  NativeStackScreenProps<RootStackParamList, Screen>;

export type Props = NativeStackScreenProps<RootStackParamList>;

RootJokeStack.tsx

const RootJokeStack = () => {
  return (
    <JokeSearch.Navigator initialRouteName="HomeScreen">
      <JokeSearch.Screen
        name="HomeScreen"
        component={HomeScreen}
        options={() => ({
          headerShown: false,
        })}
      />
      <JokeSearch.Screen
        name="CategoryDetailScreen"
        component={CategoryDetailScreen}
        options={() => ({
          headerShown: false,
        })}
      />

      <JokeSearch.Screen
        name="SeachDetailScreen"
        component={SeachDetailScreen}
        options={() => ({
          headerShown: false,
        })}
      />
    </JokeSearch.Navigator>
  );
};
;
export default RootJokeStack;

HomeScreen.tsx

<FlatList
        data={categories}
        keyExtractor={(item) => item}
        renderItem={({ item }) => (
          <TouchableWithoutFeedback
            onPress={() => {
              navigation.navigate("CategoryDetailScreen", { category: item });
            }}
          >
            <View style={styles.imageView}>
              <ImageBackground
                style={styles.image}
                source={{
                  uri: "https://media.gettyimages.com/photos/chuck-norris-poses-with-two-uzis-his-sleeveless-denim-shirt-to-his-picture-id525603356",
                }}
              >
                <View style={styles.textView}>
                  <Text style={{ color: colors.cardBackground }}>{item}</Text>
                </View>
              </ImageBackground>
            </View>
          </TouchableWithoutFeedback>
        )}
        showsVerticalScrollIndicator={false}
        ListHeaderComponent={<Text style={styles.listHeader}>Categories</Text>}
        horizontal={false}
        numColumns={2}
      />

CategoryDetailScreen.tsx

const CategoryDetailScreen = ({ route, navigation }: Props) => {
  const [categoryDetails, setcategoryDetails] = React.useState<Category>();
  // console.log(route?.params?.category);

  const query: string = route?.params?.category;

  const getCategoryDetails = async () => {
    try {
      const response = await chuckNorris.get(`/random?category=${query}`);
      return response.data;
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    getCategoryDetails().then((data) => {
      setcategoryDetails(data);
    });
  }, [query]);

SeachDetailScreen.tsx

const SeachDetailScreen = ({ route }: Props) => {
  const query = route?.params?.data;

  return (
    <View style={styles.container}>
      <SearchBarTitle data={query} />
      <FlatList
        data={query}
        keyExtractor={(item) => item}
        renderItem={({ item }) =>
          item ? (
            <View style={{ margin: 5 }}>
              <Text style={{ color: "#fff", fontSize: 20 }}>{item}</Text>
            </View>
          ) : null
        }
        showsVerticalScrollIndicator={false}
      />
    </View>
  );
};

Click here to see the error route.params.category error

Click here to see the error route.params.data error

1

There are 1 best solutions below

0
zackOverflow On

After 23 days, I finally got solution to my question and this is how I got it fixed.

I imported the RootStackScreenProps from the type.tsx file into both the CategoryDetailScreen.tsx and SeachDetailScreen.tsx. I then replace the Props types with the RootStackScreenProps as follows and boom!!!

SeachDetailScreen.tsx

import { RootStackScreenProps } from "../../type";

const SeachDetailScreen = ({
  route,
}: RootStackScreenProps<"SeachDetailScreen">) => {
  const query = route.params.data;
  ---------
  ---------
  ---------
}

CategoryDetailScreen.tsx

import { RootStackScreenProps} from "../../type";

const CategoryDetailScreen = ({
  route,
  navigation,
}: RootStackScreenProps<"CategoryDetailScreen">) => {
  const [categoryDetails, setcategoryDetails] = React.useState<Category>();

  const query = route.params.category;
  ---------
  ---------
  ---------
}

Another way it could be done is to import NativeStackNavigationProp and RouteProp from @react-navigation/native-stack and @react-navigation/native respectively into type.tsx file and use it as follows. types.tsx

import type {
  NativeStackScreenProps,
  NativeStackNavigationProp,
} from "@react-navigation/native-stack"; //
import { RouteProp } from "@react-navigation/native";

------------------------------------------------------
------------------------------------------------------
------------------------------------------------------
------------------------------------------------------

export type StackScreenProps<T extends keyof RootStackParamList> = {
  navigation: NativeStackNavigationProp<RootStackParamList, T>;
  route: RouteProp<RootStackParamList, T>;
};

and then import and use StackScreenProps in SeachDetailScreen.tsx and CategoryDetailScreen.tsx to replace RootStackScreenProps. Voila!!!