Loading...
Loading...
Compare original and translation side by side
| Dimension | Question |
|---|---|
| Architectural Fit | Does this align with feature-based structure and Suspense model? |
| Complexity Load | How complex is state, data, and interaction logic? |
| Performance Risk | Does it introduce rendering, bundle, or CLS risk? |
| Reusability | Can this be reused without modification? |
| Maintenance Cost | How hard will this be to reason about in 6 months? |
| 维度 | 问题 |
|---|---|
| 架构适配性 | 是否符合基于功能的结构与Suspense模型? |
| 复杂度负载 | 状态、数据与交互逻辑的复杂程度如何? |
| 性能风险 | 是否会引入渲染、包体积或CLS(累积布局偏移)风险? |
| 可复用性 | 无需修改即可复用吗? |
| 维护成本 | 6个月后理解该代码的难度如何? |
FFCI = (Architectural Fit + Reusability + Performance) − (Complexity + Maintenance Cost)-5 → +15FFCI = (Architectural Fit + Reusability + Performance) − (Complexity + Maintenance Cost)-5 → +15| FFCI | Meaning | Action |
|---|---|---|
| 10–15 | Excellent | Proceed |
| 6–9 | Acceptable | Proceed with care |
| 3–5 | Risky | Simplify or split |
| ≤ 2 | Poor | Redesign |
| FFCI分数 | 含义 | 行动建议 |
|---|---|---|
| 10–15 | 优秀 | 直接推进 |
| 6–9 | 可接受 | 谨慎推进 |
| 3–5 | 有风险 | 简化或拆分功能 |
| ≤ 2 | 较差 | 重新设计 |
useSuspenseQueryisLoadinguseSuspenseQueryisLoadingfeatures/components/features/components/anyimport typeanyimport typeReact.FC<Props><SuspenseLoader>useSuspenseQueryuseCallbackuseMuiSnackbarReact.FC<Props><SuspenseLoader>useSuspenseQueryuseCallbackuseMuiSnackbarfeatures/{feature-name}/api/components/hooks/helpers/types/api/index.tsroutes/features/{feature-name}/api/components/hooks/helpers/types/api/index.tsroutes/| Alias | Path |
|---|---|
| |
| |
| |
| |
| 别名 | 路径 |
|---|---|
| |
| |
| |
| |
useMemouseCallbackuseMemouseCallbackconst HeavyComponent = React.lazy(() => import('./HeavyComponent'));<SuspenseLoader>const HeavyComponent = React.lazy(() => import('./HeavyComponent'));<SuspenseLoader>useSuspenseQueryuseSuspenseQueryisLoadingisLoading/api//api/export const Route = createFileRoute('/my-route/')({
component: MyPage,
loader: () => ({ crumb: 'My Route' }),
});export const Route = createFileRoute('/my-route/')({
component: MyPage,
loader: () => ({ crumb: 'My Route' }),
});<100 linessx>100 lines{Component}.styles.tssx{Component}.styles.ts<Grid size={{ xs: 12, md: 6 }} /> // ✅
<Grid xs={12} md={6} /> // ❌<Grid size={{ xs: 12, md: 6 }} /> // ✅
<Grid xs={12} md={6} /> // ❌useMuiSnackbaruseMuiSnackbaruseMemouseCallbackReact.memouseMemouseCallbackReact.memoanyanysrc/
features/
my-feature/
api/
components/
hooks/
helpers/
types/
index.ts
components/
SuspenseLoader/
CustomAppBar/
routes/
my-route/
index.tsxsrc/
features/
my-feature/
api/
components/
hooks/
helpers/
types/
index.ts
components/
SuspenseLoader/
CustomAppBar/
routes/
my-route/
index.tsximport React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/feature';
interface MyComponentProps {
id: number;
onAction?: () => void;
}
export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
const [state, setState] = useState('');
const { data } = useSuspenseQuery<FeatureData>({
queryKey: ['feature', id],
queryFn: () => featureApi.getFeature(id),
});
const handleAction = useCallback(() => {
setState('updated');
onAction?.();
}, [onAction]);
return (
<Box sx={{ p: 2 }}>
<Paper sx={{ p: 3 }}>
{/* Content */}
</Paper>
</Box>
);
};
export default MyComponent;import React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/feature';
interface MyComponentProps {
id: number;
onAction?: () => void;
}
export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
const [state, setState] = useState('');
const { data } = useSuspenseQuery<FeatureData>({
queryKey: ['feature', id],
queryFn: () => featureApi.getFeature(id),
});
const handleAction = useCallback(() => {
setState('updated');
onAction?.();
}, [onAction]);
return (
<Box sx={{ p: 2 }}>
<Paper sx={{ p: 3 }}>
{/* Content */}
</Paper>
</Box>
);
};
export default MyComponent;components/components/