Home > other >  How to send params with navigation correctly?
How to send params with navigation correctly?

Time:02-28

I'm using navigation.navigate to move between screens but I face the following problem.

I call the method to navigate:

const FileCard = ({ fileDetails }: Props) => {
  
  const navigation = useNavigation();

  const loadDetails = () => {
    console.log(JSON.stringify(fileDetails));
    navigation.navigate("FileDetailScreen" as never, {file: 
    fileDetails} as never)
  }

And I would like to connect with this screen:

interface Props {
    file: FileInfo
  }

const FileDetailScreen = ({ file }: Props) => {
        
  return (
    <View style={globalStyles.post_login_container}>
      <Text>
          {
              (file) ?
              <Text>Exists</Text>
              :
              <Text>Does not exists</Text>
          }
    </Text>
    </View>
  )
}

But I get "Does not exists" in my screen, so I can't show the information.

enter image description here

How can I fix this problem? Thanks!

EDIT

I call the loadDetails function here:

    <TouchableOpacity
      activeOpacity={0.8}
      onPress={() => {loadDetails(fileInfo)}}
    >

    // Elements and styles

    </TouchableOpacity>

And this is my stack navigation:

    <Stack.Navigator
    screenOptions={{
        headerShown: false,
        cardStyleInterpolator: CardStyleInterpolators.forFadeFromBottomAndroid
    }}>
      <Stack.Screen name="LoginScreen" component={LoginScreen} />
      <Stack.Screen name="RegisterScreen" component={RegisterScreen} />
      <Stack.Screen name="ControlScreen" component={ControlScreen} />
      <Stack.Screen name="ProfileScreen" component={ProfileScreen} />
      <Stack.Screen name="FilesScreen" component={FilesScreen} />
      <Stack.Screen name="UploadFileScreen" component={UploadFileScreen} />
      <Stack.Screen name="SearchScreen" component={SearchScreen} />
      <Stack.Screen name="ResultsScreen" component={ResultsScreen} />

// THE SCREEN
      <Stack.Screen name="FileDetailScreen" component={FileDetailScreen} />

    </Stack.Navigator>

CodePudding user response:

You are passing the props for FileDetailScreen using the navigation route param props. If you have a screen

const FileDetailScreen = ({ file }: Props) => {

...

} 

then file is a prop of the JSX component, e.g.

const SomeOtherScreen = () => {

    return <FileDetailScreen file={someFile} />
}

This is different then passing a prop using the route params. If we want to navigate to FileDetailScreen and pass the file prop using

navigation.navigate("FileDetailScreen" as never, {file: fileDetails} as never)

you are not instantiating a new JSX component, but you are passing route params. We can access them as follows.

const FileDetailScreen = ({file, route}) {

 const f = route.params?.file
}

Notice that route is passed by the Navigator. Being precise here, we should add this to the props interface of your screen to satisfy TypeScript. This is very well documented here.

Edit: Since it was explicitly requested to solve the TypeScript error, we are going to solve this as well.

  1. Create a type, e.g. RootStackParams where we need to provide the types for all route params.

export type RouteStackParams = {

    FileDetailScreen: { 
        file: FileInfo
    }

    ...
}

Notice that you need to do this for all your routes in order to provide correct types for the TypeScript compiler.

  1. Create your Stack.Navigator by providing the route param types as follows.
const Stack = createStackNavigator<RouteStackParams>()

Your FileDetailScreen is now correctly typed. Notice as well that this does not effect your runtime behavior, thus your code would work without doing this.

  • Related