【问题标题】:React-native : Dynamically update header title in stack navigatorReact-native:动态更新堆栈导航器中的标题标题
【发布时间】:2017-09-13 14:41:18
【问题描述】:

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

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

【问题讨论】:

标签: react-native react-navigation


【解决方案1】:

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

您可以在组件中使用this.props.navigation.state.params 来设置新属性。调用:

navigation.setParams({ param: value })

更多详情请参阅the documentation on headers

【讨论】:

  • @mehulmpt 抱歉,他们更改了文档。我更新了。
  • 使用 react 5.0 或更高版本你可以简单地做this.props.navigation.setOptions({title: newTitle})
  • @KewalShah 实际上是:props.navigation.setOptions({ headerTitle: newTitle, }); 目前
【解决方案2】:

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

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

5.x 及以上版本可参考以下代码。这是official documentationexample in expo 的链接。

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;

【讨论】:

  • 如何在反应导航 5.x 上动态更改标题标题
  • @Rizwan 我添加了 5.x 版本的示例
  • 任何建议我们如何在类组件中做到这一点?我可以使用 this.props.navigation.setOptions 显示 headerRight 但 onPress 不会触发类组件。
【解决方案3】:

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

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

【讨论】:

  • 这是最好的,这很容易满足我的需要
  • 我在使用此解决方案时遇到问题,我使用 useRoute 将对象作为参数传递给我的应用程序的详细信息屏幕,但是当我使用上面的代码或一般添加选项并在 app.js 中使用它时某些原因它不起作用也不确定如何将路由参数传递给 app.js。抱歉,如果它看起来对反应和编程有点陌生
【解决方案4】:

使用 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]);

【讨论】:

    【解决方案5】:

    以下部分显示的代码适用于 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

    【讨论】:

      【解决方案6】:
       navigation.setOptions({ title: 'Updated!' })
      

      Reference.

      【讨论】:

      • 完美答案。
      【解决方案7】:

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

      对于类compensent,

      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'),
      })
      

      【讨论】:

        【解决方案8】:

        用于反应导航版本: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

        【讨论】:

        • 我们收到警告,无法从不同组件的函数体内更新组件。
        【解决方案9】:
        function App() {
          return (
            <NavigationContainer>
              <Stack.Navigator>
                <Stack.Screen
                  name="OrdersScreen"
                  component={OrdersScreen}
                  options={{ title: 'My Orders' }}
                />
              </Stack.Navigator>
            </NavigationContainer>
          );
        }
        

        【讨论】:

          【解决方案10】:

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

          类组件:

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

          功能组件:

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

          【讨论】:

            【解决方案11】:

            如果你使用 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,
            });
            

            来自doc

            这样称呼它:

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

            【讨论】:

              【解决方案12】:

              对于第 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"
                  });
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-11-25
                • 1970-01-01
                • 2020-05-11
                • 2022-07-17
                相关资源
                最近更新 更多