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

React-native : Dynamically update header title in stack navigator

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

所以我的问题是如何change/update动态标题?

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

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

navigation.setParams({ param: value })

有关详细信息,请参阅 the documentation on headers

下面部分显示的代码是针对 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

对于 React Navigation 版本 1.x、2.x、3.x 和 4.x,您可以使用下面显示的方法简单地更改 header下面的代码,或原始文档中的代码: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 documentation and example 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;

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

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

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

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

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

Reference.

在版本 3.x 和 4.x 中,这可以使用静态导航选项功能完成,

对于class个组件,

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'),
})
function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="OrdersScreen"
          component={OrdersScreen}
          options={{ title: 'My Orders' }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

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

Class 分量:

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

函数组件:

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

如果您使用 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})}

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