React-native:动态更新堆栈导航器中的标题标题

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

我为标题标题(堆栈导航器)制作了一个自定义组件,它显示用户名和一些图像。 在此页面上,我必须编辑用户名,成功后也在标题中更新它

所以我的问题是如何动态更改/更新标题?

react-native react-navigation
13个回答
40
投票

这可以使用导航道具来完成。

您可以在组件中使用

this.props.navigation.state.params
来设置新属性。致电:

navigation.setParams({ param: value })

请参阅有关标头的文档了解更多详细信息。


40
投票

对于 React Navigation 1.x、2.x、3.x 和 4.x 版本,您可以使用下面代码中所示的方法或原始文档中的方法简单地更改标头: React Navigation - using标题中的参数

     static navigationOptions = ({ navigation }) => {
        const edit = navigation.getParam('edit', false);
        if(edit){
          return {
            headerTitle: 'Edit Page',
          };
        }else{
          return {
            headerTitle: 'Normal Page',
          };
        }
     };

对于5.x及以上版本,您可以参考以下代码。以下是官方文档博览会中的示例的链接。

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

    function HomeScreen({ navigation }) {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Home Screen</Text>
          <Button
            title="Go to Profile"
            onPress={() =>
              navigation.navigate('Profile', { name: 'Custom profile header' })
            }
          />
        </View>
      );
    }
    
    function ProfileScreen({ navigation }) {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>Profile screen</Text>
          <Button title="Go back" onPress={() => navigation.goBack()} />
        </View>
      );
    }
    
    const Stack = createStackNavigator();
    
    function App() {
      return (
        <NavigationContainer>
          <Stack.Navigator>
            <Stack.Screen
              name="Home"
              component={HomeScreen}
              options={{ title: 'My home' }}
            />
            <Stack.Screen
              name="Profile"
              component={ProfileScreen}
              options={({ route }) => ({ title: route.params.name })}
            />
          </Stack.Navigator>
        </NavigationContainer>
      );
    }
    
    export default App;

37
投票

React 5.0 或更高版本中,如果你想使用类组件,你可以执行以下操作:

 componentDidMount() {
   this.props.navigation.setOptions({
     title: `Your Updated Title`,
   })
 }

24
投票

使用 React Navigation 5React Navigation 6 你可以这样做, 在组件中设置参数

props.navigation.navigate("ProductDetailScreen", {
      productId: itemData.item.id,
      productTitle: itemData.item.title,
    });

并显示它

<Stack.Screen
      name="ProductDetailScreen"
      component={ProductDetailScreen}
      options={({ route }) => ({ title: route.params.productTitle })} // what 
need to add
/>

您可以在组件中使用

useEffect
钩子

执行此操作
useEffect(() => {
    props.navigation.setOptions({
      title: productTitle,
    });
  }, [productTitle, props.navigation]);

13
投票
 navigation.setOptions({ title: 'Updated!' })

参考.


4
投票

下面部分显示的代码适用于react-navigation 2.x版本

您可以尝试以下方法:

就我而言,我在名为 app-navigator.js 的文件中配置了导航

const ChatStackNavigator = createStackNavigator(
    {
        People: ListPeopleScreen, // People Screen,
        Screen2: Screen2
    },
    {
        initialRouteName: 'People'
        navigationOptions: ({navigation}) => ({
            header: <AppBar title={navigation.getParam('appBar', {title: ''}).title}/>
        }),
        cardStyle: {
            backgroundColor: 'white'
        }
    }
);

屏幕文件如下:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import {List, ListItem} from 'react-native-elements';

class ListPeopleScreen extends Component {

    list = [
        {
            name: 'Amy Farha',
            avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
            subtitle: 'Vice President'
        },
        {
            name: 'Chris Jackson',
            avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
            subtitle: 'Vice Chairman'
        }
    ];

    componentDidMount() {
        this.props.navigation.setParams({
            appBar: {
                title: 'Clientes'
            }
        });
    }

    render() {
        return <List
            containerStyle={{marginBottom: 30}}
        >
            {
                this.list.map((item) => (
                    <ListItem
                        roundAvatar
                        avatar={{uri: item.avatar_url}}
                        key={item.name}
                        title={item.name}
                    />
                ))
            }
        </List>
    };
}

export default connect(null)(ListPeopleScreen);

注意:在我的例子中,我使用的是 redux 和组件库 react-native-elements


3
投票

在版本 3.x 和 4.x 中,这可以使用静态 navigationOptions 函数来完成,

对于类组件,

class MyComponent extends Component {
  static navigationOptions = ({navigation}) => {
    return {
      title: navigation.getParam('title', 'Fallback title');
    };
  }

  updateHeader = () => {
    // dynamically update header
    navigation.setParams({title: 'MyComponent'});
  }

  render() {
    // call updateHeader on click of any component
  }
}

对于功能组件,

const MyComponent = (props) => {
  const updateHeader = () => {
    // dynamically update header
    navigation.setParams({title: 'MyComponent'});
  }

  // call updateHeader on click of any component
}

MyComponent.navigationOptions = ({navigation}) => ({
  title: navigation.getParam('title', 'Fallback title'),
})

2
投票

用于反应导航版本:5.x

   const ProductDetailScreen = props => {
       const { productId } = props.route.params;
       const { productTitle } = props.route.params;

       props.navigation.setOptions({ title: productTitle });

       return  (
            <View>
                <Text>{productId}</Text>
            </View>
        );
     };

用于反应导航版本:5.x


1
投票

对于版本 4,这对我来说是有用的。

    const HistoryScreen: NavigationStackScreenComponent<any, any> = (props) => {
  const { navigation } = props;

  useEffect(() => {
    let device = props.navigation.getParam("device");
    if(device) {
        navigation.setParams({title: `History - ${device.name}`})
    }
  }, []);

    ... render view

    HistoryScreen.navigationOptions = ({
      navigationOptions,
      navigation,
    }) => ({
      headerTitle: navigation.getParam("title") ? navigation.getParam("title") : "History"
    });
}

0
投票
function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="OrdersScreen"
          component={OrdersScreen}
          options={{ title: 'My Orders' }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

0
投票

对于 React-Navigation v3,我使用以下命令来更改堆栈的标题:

类组件:

this.props.navigation.setParams({ title: res.title });

功能组件:

props.navigation.setParams({ title: res.title });

0
投票

如果你使用createStackNavigator,你可以这样做:

createStackNavigator({
  // For each screen that you can navigate to, create a new entry like this:
  Profile: {
    // `ProfileScreen` is a React component that will be the main content of the screen.
    screen: ProfileScreen,
    // When `ProfileScreen` is loaded by the StackNavigator, it will be given a `navigation` prop.

    // Optional: When deep linking or using react-navigation in a web app, this path is used:
    path: 'people/:name',
    // The action and route params are extracted from the path.

    // Optional: Override the `navigationOptions` for the screen
    navigationOptions: ({ navigation }) => ({
      title: `${navigation.state.params.name}'s Profile'`,
    }),
  },

  ...MyOtherRoutes,
});

来自文档

这样称呼它:

navigation.navigate('Profile', {_id: item._id, name: item.screenName})}

0
投票

将react-native与expo一起使用时,您可以访问globalSearchParams并从屏幕参数中获取标题。

import {Stack, useGlobalSearchParams} from 'expo-router';

export default function StackLayout() {
    const global = useGlobalSearchParams();

    return (
        <Stack>
            <Stack.Screen
                name="myscreen"
                options={{
                    title: "" + (global?.screenTitle ? global.screenTitle : ''),
                    headerShown: true,
                }}
            />
        </Stack>
    )

导航时:

import {router} from 'expo-router';
...
router.replace({pathname: '/scoreboard', params: {gameId, gameName}});
© www.soinside.com 2019 - 2024. All rights reserved.