简体   繁体   中英

Change screen with a header button on the latest version of react-navigation v5.0

I can't seem to find anything that is up to date here about changing screens with the header button. So I am wondering what the correct syntax is for the header button to change screens nowadays. I have defined my header in my navigation stack code file where I make the header but I can't seem to figure how to get the navigation prop and be able to call it on the header. some answers say to use navigation Options or make it static but from the documentation (which never explains how to do this) there is nothing in the correct version about navigation options so I think they removed. Also when I try the code nothing works. Thank you for all your help and hopefully, I can get an answer or find out what the correct syntax would be.

here is my current version of my code. it says navigate is not a function when I hit the button:

import React from 'react';
import {Button} from 'react-native';
import {createStackNavigator} from '@react-navigation/stack';
import {NavigationContainer} from '@react-navigation/native';
import Home from '../Views/Home';
import AddTask from '../Views/AddTask';

const Stack = createStackNavigator();

const HomeStack = ({navigate}) => {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen
          name="Home"
          component={Home}
          options={{
            headerStyle: {backgroundColor: 'darkslateblue'},
            headerRight: () => (
              <Button
                onPress={() => navigate('Add Task')}
                title="Add Task"
                color="#000000"
              />
            ),
          }}
        />
        <Stack.Screen
          name="Add Task"
          component={AddTask}
          options={{
            headerStyle: {backgroundColor: 'darkslateblue'},
          }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default HomeStack;

I havent found a method of doing this within App.js but found you can easily implement this from within a component or screen that has access to the navigator via useNavigation.

For example, here is my App.js that does not define the header button:

 import 'react-native-gesture-handler'; import * as React from 'react'; import { Button } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import IndexScreen from './src/screens/IndexScreen'; import ShowScreen from './src/screens/ShowScreen'; import CreateScreen from './src/screens/CreateScreen'; import { Provider } from './src/context/BlogContext'; const Stack = createStackNavigator(); const App = () => { return ( <Provider> <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Index" component={IndexScreen} options={{ title: 'Blogs', }} /> <Stack.Screen name="Show" component={ShowScreen} options={{ title: 'Show Screen' }} /> <Stack.Screen name="Create" component={CreateScreen} options={{ title: 'New Post' }} /> </Stack.Navigator> </NavigationContainer> </Provider> ); } export default App;

And here is an example of a screen where I add a headerRight button that navigates to another screen:

 import React, { useContext } from 'react'; import { useNavigation } from '@react-navigation/native'; import {View, Text, StyleSheet, FlatList, Button, TouchableOpacity} from 'react-native'; import { Context } from '../context/BlogContext'; import { Feather } from '@expo/vector-icons'; const IndexScreen = () => { const {state, addBlogPost, deleteBlogPost} = useContext(Context); const navigation = useNavigation(); navigation.setOptions({ headerRight: () => ( <Button title="Add Post" onPress={() => navigation.navigate('Create')} /> ), }); return ( <View style={styles.containerStyle}> <Text style={styles.titleStyle}>Index Screen</Text> <FlatList horizontal={false} data={state} keyExtractor={(item) => item.title} renderItem={({item}) => { return ( <TouchableOpacity onPress={navigation.navigate('Show', { id: item.id })}> <View style={styles.blogPostStyle}> <Text style={styles.blogPostTitleStyle}>{item.title}</Text> <TouchableOpacity onPress={() => { deleteBlogPost(item.id); }}> <Feather name="trash" style={styles.deleteIconStyle} /> </TouchableOpacity> </View> </TouchableOpacity> ); }} /> </View> ); }; const styles = StyleSheet.create({ containerStyle: { margin: 10 }, titleStyle: { }, blogPostStyle: { flexDirection: 'row', justifyContent: 'space-between', paddingVertical: 20, borderTopWidth: 1, color: 'gray' }, blogPostTitleStyle: { fontSize: 18 }, deleteIconStyle: { fontSize: 24 } }); export default IndexScreen;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM