refactor(navigation): replace direct navigation with navigation service
Replace direct `navigation.navigate()` and `navigation.getParent()?.navigate()` calls with centralized `navigationService.navigate()` across multiple screens. Convert screen component functions from JSX elements to array-returning functions in RootNavigator to fix React key warnings and improve render consistency. - HomeScreen: use navigationService for post and user navigation - PrivateChatInfoScreen: use navigationService for profile navigation - ChatScreen: use navigationService for avatar press and user profile navigation - RootNavigator: convert PublicScreens and AuthenticatedScreens to getPublicScreens() and getAuthenticatedScreens() functions returning arrays with proper keys
This commit is contained in:
@@ -41,10 +41,10 @@ interface RootNavigatorProps {
|
||||
isInitializing: boolean;
|
||||
}
|
||||
|
||||
// 未认证时可访问的屏幕
|
||||
const PublicScreens = () => (
|
||||
<>
|
||||
// 未认证时可访问的屏幕 - 返回数组而不是 JSX
|
||||
const getPublicScreens = () => [
|
||||
<RootStack.Screen
|
||||
key="PostDetail"
|
||||
name="PostDetail"
|
||||
component={PostDetailScreen}
|
||||
options={{
|
||||
@@ -54,8 +54,9 @@ const PublicScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="UserProfile"
|
||||
name="UserProfile"
|
||||
component={UserScreen}
|
||||
options={{
|
||||
@@ -64,14 +65,13 @@ const PublicScreens = () => (
|
||||
headerStyle: { backgroundColor: colors.background.paper },
|
||||
headerTintColor: colors.text.primary,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
/>,
|
||||
];
|
||||
|
||||
// 认证后可访问的屏幕
|
||||
const AuthenticatedScreens = () => (
|
||||
<>
|
||||
// 认证后可访问的屏幕 - 返回数组而不是 JSX
|
||||
const getAuthenticatedScreens = () => [
|
||||
<RootStack.Screen
|
||||
key="PostDetail"
|
||||
name="PostDetail"
|
||||
component={PostDetailScreen}
|
||||
options={{
|
||||
@@ -81,8 +81,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="UserProfile"
|
||||
name="UserProfile"
|
||||
component={UserScreen}
|
||||
options={{
|
||||
@@ -91,8 +92,9 @@ const AuthenticatedScreens = () => (
|
||||
headerStyle: { backgroundColor: colors.background.paper },
|
||||
headerTintColor: colors.text.primary,
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="CreatePost"
|
||||
name="CreatePost"
|
||||
component={CreatePostScreen}
|
||||
options={{
|
||||
@@ -102,16 +104,18 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
presentation: 'modal',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="Chat"
|
||||
name="Chat"
|
||||
component={ChatScreen}
|
||||
options={{
|
||||
headerShown: false,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="FollowList"
|
||||
name="FollowList"
|
||||
component={FollowListScreen}
|
||||
options={{
|
||||
@@ -121,8 +125,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="CreateGroup"
|
||||
name="CreateGroup"
|
||||
component={CreateGroupScreen}
|
||||
options={{
|
||||
@@ -132,8 +137,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
presentation: 'modal',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="JoinGroup"
|
||||
name="JoinGroup"
|
||||
component={JoinGroupScreen}
|
||||
options={{
|
||||
@@ -143,8 +149,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="GroupInfo"
|
||||
name="GroupInfo"
|
||||
component={GroupInfoScreen}
|
||||
options={{
|
||||
@@ -154,8 +161,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="GroupMembers"
|
||||
name="GroupMembers"
|
||||
component={GroupMembersScreen}
|
||||
options={{
|
||||
@@ -165,8 +173,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="GroupRequestDetail"
|
||||
name="GroupRequestDetail"
|
||||
component={GroupRequestDetailScreen}
|
||||
options={{
|
||||
@@ -176,8 +185,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="GroupInviteDetail"
|
||||
name="GroupInviteDetail"
|
||||
component={GroupInviteDetailScreen}
|
||||
options={{
|
||||
@@ -187,8 +197,9 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
/>,
|
||||
<RootStack.Screen
|
||||
key="PrivateChatInfo"
|
||||
name="PrivateChatInfo"
|
||||
component={PrivateChatInfoScreen}
|
||||
options={{
|
||||
@@ -198,9 +209,8 @@ const AuthenticatedScreens = () => (
|
||||
headerTintColor: colors.text.primary,
|
||||
animation: 'slide_from_right',
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
/>,
|
||||
];
|
||||
|
||||
export function RootNavigator({ isAuthenticated, isInitializing }: RootNavigatorProps) {
|
||||
const { isMobile } = useResponsive();
|
||||
@@ -238,7 +248,7 @@ export function RootNavigator({ isAuthenticated, isInitializing }: RootNavigator
|
||||
)
|
||||
}
|
||||
</RootStack.Screen>
|
||||
<AuthenticatedScreens />
|
||||
{getAuthenticatedScreens()}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
@@ -247,7 +257,7 @@ export function RootNavigator({ isAuthenticated, isInitializing }: RootNavigator
|
||||
component={AuthNavigator}
|
||||
options={{ headerShown: false }}
|
||||
/>
|
||||
<PublicScreens />
|
||||
{getPublicScreens()}
|
||||
</>
|
||||
)}
|
||||
</RootStack.Navigator>
|
||||
|
||||
@@ -35,6 +35,7 @@ import { HomeStackParamList, RootStackParamList } from '../../navigation/types';
|
||||
import { useResponsive, useResponsiveSpacing } from '../../hooks/useResponsive';
|
||||
import { SearchScreen } from './SearchScreen';
|
||||
import { CreatePostScreen } from '../create/CreatePostScreen';
|
||||
import { navigationService } from '../../infrastructure/navigation/navigationService';
|
||||
|
||||
type NavigationProp = NativeStackNavigationProp<HomeStackParamList, 'Home'> & NativeStackNavigationProp<RootStackParamList>;
|
||||
|
||||
@@ -343,12 +344,12 @@ export const HomeScreen: React.FC = () => {
|
||||
|
||||
// 跳转到帖子详情
|
||||
const handlePostPress = (postId: string, scrollToComments: boolean = false) => {
|
||||
navigation.getParent()?.navigate('PostDetail', { postId, scrollToComments });
|
||||
navigationService.navigate('PostDetail', { postId, scrollToComments });
|
||||
};
|
||||
|
||||
// 跳转到用户主页
|
||||
const handleUserPress = (userId: string) => {
|
||||
navigation.getParent()?.navigate('UserProfile', { userId });
|
||||
navigationService.navigate('UserProfile', { userId });
|
||||
};
|
||||
|
||||
// 点赞帖子
|
||||
|
||||
@@ -31,6 +31,7 @@ import { userManager } from '../../stores/userManager';
|
||||
import { Avatar, Text, Button, Loading, Divider } from '../../components/common';
|
||||
import { User } from '../../types';
|
||||
import { RootStackParamList, MessageStackParamList } from '../../navigation/types';
|
||||
import { navigationService } from '../../infrastructure/navigation/navigationService';
|
||||
|
||||
type NavigationProp = NativeStackNavigationProp<MessageStackParamList>;
|
||||
type PrivateChatInfoRouteProp = RouteProp<MessageStackParamList, 'PrivateChatInfo'>;
|
||||
@@ -149,9 +150,8 @@ const PrivateChatInfoScreen: React.FC = () => {
|
||||
|
||||
// 查看用户资料
|
||||
const handleViewProfile = () => {
|
||||
// 使用根导航跳转到用户资料页面
|
||||
const rootNavigation = navigation.getParent();
|
||||
rootNavigation?.navigate('UserProfile' as any, { userId });
|
||||
// 使用导航服务跳转到用户资料页面
|
||||
navigationService.navigate('UserProfile', { userId });
|
||||
};
|
||||
|
||||
// 举报/投诉
|
||||
|
||||
@@ -31,6 +31,7 @@ import { groupService } from '../../../../services/groupService';
|
||||
import { userManager } from '../../../../stores/userManager';
|
||||
import { groupManager } from '../../../../stores/groupManager';
|
||||
import { RootStackParamList } from '../../../../navigation/types';
|
||||
import { navigationService } from '../../../../infrastructure/navigation/navigationService';
|
||||
import {
|
||||
GroupMessage,
|
||||
PanelType,
|
||||
@@ -1039,9 +1040,9 @@ export const useChatScreen = () => {
|
||||
// 点击头像跳转到用户主页
|
||||
const handleAvatarPress = useCallback((userId: string) => {
|
||||
if (userId && userId !== currentUserId) {
|
||||
navigation.navigate('UserProfile' as any, { userId: String(userId) });
|
||||
navigationService.navigate('UserProfile', { userId: String(userId) });
|
||||
}
|
||||
}, [navigation, currentUserId]);
|
||||
}, [currentUserId]);
|
||||
|
||||
// 长按头像@用户
|
||||
const handleAvatarLongPress = useCallback((senderId: string, nickname: string) => {
|
||||
@@ -1113,8 +1114,7 @@ export const useChatScreen = () => {
|
||||
conversationId: conversationId || undefined,
|
||||
});
|
||||
} else if (otherUser?.id) {
|
||||
const rootNavigation = navigation.getParent();
|
||||
rootNavigation?.navigate('UserProfile' as any, { userId: String(otherUser.id) });
|
||||
navigationService.navigate('UserProfile', { userId: String(otherUser.id) });
|
||||
}
|
||||
}, [navigation, isGroupChat, routeGroupId, otherUser]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user