You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Navigation 6及以上版本如何从组件向导航器头部传递props?

React Navigation 6 实现头部未读通知计数

方案一:Props 传递(简单场景)

适合通知状态仅在初始化时获取、后续无需更新的场景。

  1. 在App组件中维护未读计数状态
    修正原代码异步逻辑的问题,将未读计数存入状态并传递给导航组件:
const App = () => {
    const [notifications, setNotifications] = useState([]);
    const [unreadCount, setUnreadCount] = useState(0);

    useEffect(() => {
        const fetchNotifications = async () => {
            const fetchedNotifications = await API.fetch();
            setNotifications(fetchedNotifications);
            // 计算未读数量
            const count = fetchedNotifications.filter(n => !n.isRead).length;
            setUnreadCount(count);
        };
        fetchNotifications();
    }, []);

    return (
        <NavigationContainer>
            <MyStack unreadCount={unreadCount} />
        </NavigationContainer>
    );
}
  1. 将计数传递到Tab导航组件
    修改MyStack,把unreadCount传递给MyTabs:
const MyStack = ({ unreadCount }) => {
    const navigation = useNavigation();
    return (
        <Stack.Navigator>
            <Stack.Group>
                <Stack.Screen name="Tabs" options={{ headerShown: false }}>
                    {(props) => <MyTabs {...props} unreadCount={unreadCount} />}
                </Stack.Screen>

                {/* 原有Notifications屏幕代码不变 */}
            </Stack.Group>
        </Stack.Navigator>
    );
}
  1. 在Tab导航头部显示计数
    修改MyTabs的headerRight,添加未读计数标记:
const MyTabs = ({ unreadCount }) => {
    const navigation = useNavigation();
    return (
        <Tab.Navigator
            screenOptions={{
                headerRight: () => (
                    <TouchableOpacity 
                        onPress={() => navigation.navigate("Notifications")}
                        style={{ position: 'relative', marginRight: 16 }}
                    >
                        <Ionicons name="notifications" size={24} color="black"/>
                        {/* 仅当有未读时显示计数 */}
                        {unreadCount > 0 && (
                            <View style={{
                                position: 'absolute',
                                top: -4,
                                right: -4,
                                backgroundColor: '#ff3b30',
                                borderRadius: 10,
                                width: 20,
                                height: 20,
                                justifyContent: 'center',
                                alignItems: 'center'
                            }}>
                                <Text style={{ color: 'white', fontSize: 12, fontWeight: 'bold' }}>
                                    {unreadCount}
                                </Text>
                            </View>
                        )}
                    </TouchableOpacity>
                )}
            }}
        >           
            {/* 你的Tab屏幕组件 */}
        </Tab.Navigator>
    );
}

方案二:React Context 管理(复杂场景)

适合需要在多个组件中更新通知状态(比如在通知列表标记已读)的场景,避免层层传递props。

  1. 创建通知状态上下文
import { createContext, useContext, useState, useEffect } from 'react';

const NotificationContext = createContext();

export const NotificationProvider = ({ children }) => {
    const [notifications, setNotifications] = useState([]);
    const [unreadCount, setUnreadCount] = useState(0);

    // 初始化获取通知
    useEffect(() => {
        const fetchNotifications = async () => {
            const fetchedNotifications = await API.fetch();
            setNotifications(fetchedNotifications);
            updateUnreadCount(fetchedNotifications);
        };
        fetchNotifications();
    }, []);

    // 更新未读计数的工具函数
    const updateUnreadCount = (notifs) => {
        const count = notifs.filter(n => !n.isRead).length;
        setUnreadCount(count);
    };

    // 标记单条通知为已读
    const markNotificationAsRead = (notificationId) => {
        const updatedNotifs = notifications.map(n => 
            n.id === notificationId ? { ...n, isRead: true } : n
        );
        setNotifications(updatedNotifs);
        updateUnreadCount(updatedNotifs);
        // 这里可添加调用API更新后端状态的逻辑
    };

    return (
        <NotificationContext.Provider 
            value={{ notifications, unreadCount, markNotificationAsRead }}
        >
            {children}
        </NotificationContext.Provider>
    );
};

// 自定义Hook简化上下文调用
export const useNotifications = () => useContext(NotificationContext);
  1. 在App中包裹导航容器
const App = () => {
    return (
        <NotificationProvider>
            <NavigationContainer>
                <MyStack />
            </NavigationContainer>
        </NotificationProvider>
    );
}
  1. 在Tab导航头部获取计数
const MyTabs = () => {
    const navigation = useNavigation();
    const { unreadCount } = useNotifications(); // 直接从上下文获取计数

    return (
        <Tab.Navigator
            screenOptions={{
                headerRight: () => (
                    <TouchableOpacity 
                        onPress={() => navigation.navigate("Notifications")}
                        style={{ position: 'relative', marginRight: 16 }}
                    >
                        <Ionicons name="notifications" size={24} color="black"/>
                        {unreadCount > 0 && (
                            <View style={{
                                position: 'absolute',
                                top: -4,
                                right: -4,
                                backgroundColor: '#ff3b30',
                                borderRadius: 10,
                                width: 20,
                                height: 20,
                                justifyContent: 'center',
                                alignItems: 'center'
                            }}>
                                <Text style={{ color: 'white', fontSize: 12, fontWeight: 'bold' }}>
                                    {unreadCount}
                                </Text>
                            </View>
                        )}
                    </TouchableOpacity>
                )}
            }}
        >           
            {/* 你的Tab屏幕组件 */}
        </Tab.Navigator>
    );
}
  1. 在通知列表中更新状态
const NotificationsScreen = () => {
    const { notifications, markNotificationAsRead } = useNotifications();

    return (
        <View style={{ padding: 16 }}>
            {notifications.map(notification => (
                <TouchableOpacity 
                    key={notification.id}
                    onPress={() => markNotificationAsRead(notification.id)}
                    style={{ 
                        paddingVertical: 12, 
                        borderBottomWidth: 1, 
                        borderBottomColor: '#eee' 
                    }}
                >
                    <Text style={{ 
                        fontWeight: notification.isRead ? 'normal' : 'bold',
                        fontSize: 16
                    }}>
                        {notification.title}
                    </Text>
                    <Text style={{ color: '#666', marginTop: 4 }}>
                        {notification.content}
                    </Text>
                </TouchableOpacity>
            ))}
        </View>
    );
}

内容的提问来源于stack exchange,提问作者user6377312

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:20:35