[ PROMPT_NODE_24794 ]
complete-examples
[ SKILL_DOCUMENTATION ]
# 完整示例
结合所有现代模式的完整工作示例:React.FC、懒加载、Suspense、useSuspenseQuery、样式、路由和错误处理。
---
## 示例 1:现代组件完整实现
结合了:React.FC、useSuspenseQuery、缓存优先、useCallback、样式、错误处理
typescript
/**
* 用户资料展示组件
* 展示了使用 Suspense 和 TanStack Query 的现代模式
*/
import React, { useState, useCallback, useMemo } from 'react';
import { Box, Paper, Typography, Button, Avatar } from '@mui/material';
import type { SxProps, Theme } from '@mui/material';
import { useSuspenseQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { userApi } from '../api/userApi';
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';
import type { User } from '~types/user';
// 样式对象
const componentStyles: Record<string, SxProps> = {
container: {
p: 3,
maxWidth: 600,
margin: '0 auto',
},
header: {
display: 'flex',
alignItems: 'center',
gap: 2,
mb: 3,
},
content: {
display: 'flex',
flexDirection: 'column',
gap: 2,
},
actions: {
display: 'flex',
gap: 1,
mt: 2,
},
};
interface UserProfileProps {
userId: string;
onUpdate?: () => void;
}
export const UserProfile: React.FC = ({ userId, onUpdate }) => {
const queryClient = useQueryClient();
const { showSuccess, showError } = useMuiSnackbar();
const [isEditing, setIsEditing] = useState(false);
// Suspense 查询 - 无需 isLoading!
const { data: user } = useSuspenseQuery({
queryKey: ['user', userId],
queryFn: () => userApi.getUser(userId),
staleTime: 5 * 60 * 1000,
});
// 更新变更
const updateMutation = useMutation({
mutationFn: (updates: Partial) =>
userApi.updateUser(userId, updates),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['user', userId] });
showSuccess('资料已更新');
setIsEditing(false);
onUpdate?.();
},
onError: () => {
showError('更新资料失败');
},
});
// 记忆化计算值
const fullName = useMemo(() => {
return `${user.firstName} ${user.lastName}`;
}, [user.firstName, user.lastName]);
// 使用 useCallback 的事件处理程序