闽公网安备 35020302035485号
// 这是我在真实项目中看到的代码模式
function ComplexDataDashboard({ projectId, userId }) {
const [projectData, setProjectData] = useState(null);
const [userData, setUserData] = useState(null);
const [permissions, setPermissions] = useState([]);
const [analytics, setAnalytics] = useState(null);
const [notifications, setNotifications] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [loadingSteps, setLoadingSteps] = useState(0);
const [error, setError] = useState(null);
const [retryCount, setRetryCount] = useState(0);
// 加载项目数据
useEffect(() => {
setIsLoading(true);
setError(null);
fetchProjectData(projectId)
.then(data => {
setProjectData(data);
setLoadingSteps(prev => prev + 1);
})
.catch(err => {
setError(err);
setIsLoading(false);
});
}, [projectId, retryCount]);
// 加载用户数据
useEffect(() => {
if (projectData) {
fetchUserData(userId)
.then(data => {
setUserData(data);
setLoadingSteps(prev => prev + 1);
});
}
}, [userId, projectData]);
// 加载权限信息
useEffect(() => {
if (userData && projectData) {
fetchUserPermissions(userId, projectData.id)
.then(perms => {
setPermissions(perms);
setLoadingSteps(prev => prev + 1);
});
}
}, [userData, projectData, userId]);
// 加载分析数据
useEffect(() => {
if (permissions.length > 0 && permissions.includes('view_analytics')) {
fetchAnalytics(projectId)
.then(data => {
setAnalytics(data);
setLoadingSteps(prev => prev + 1);
});
}
}, [permissions, projectId]);
// 加载通知
useEffect(() => {
if (userData) {
fetchNotifications(userId)
.then(notifs => {
setNotifications(notifs);
setLoadingSteps(prev => prev + 1);
});
}
}, [userData, userId]);
// 检查是否全部加载完成
useEffect(() => {
const expectedSteps = permissions.includes('view_analytics') ? 5 : 4;
if (loadingSteps >= expectedSteps) {
setIsLoading(false);
}
}, [loadingSteps, permissions]);
// 堆代码 duidaima.com
// 重试逻辑
useEffect(() => {
if (error && retryCount < 3) {
const timer = setTimeout(() => {
setRetryCount(prev => prev + 1);
}, 2000 * Math.pow(2, retryCount));
return() => clearTimeout(timer);
}
}, [error, retryCount]);
}
这种模式的问题分析优化策略一:状态聚合与原子化更新
// 定义完整的状态结构和action类型
const initialState = {
// 数据状态
projectData: null,
userData: null,
permissions: [],
analytics: null,
notifications: [],
// 加载状态
loading: {
project: false,
user: false,
permissions: false,
analytics: false,
notifications: false
},
// 全局状态
isInitialized: false,
error: null,
retryCount: 0
};
function dashboardReducer(state, action) {
switch (action.type) {
case'INIT_LOADING':
return {
...state,
loading: { ...state.loading, project: true },
error: null,
isInitialized: false
};
case'PROJECT_LOADED':
return {
...state,
projectData: action.payload,
loading: { ...state.loading, project: false, user: true }
};
case'USER_LOADED':
return {
...state,
userData: action.payload,
loading: {
...state.loading,
user: false,
permissions: true,
notifications: true
}
};
case'PERMISSIONS_LOADED':
const hasAnalyticsPermission = action.payload.includes('view_analytics');
return {
...state,
permissions: action.payload,
loading: {
...state.loading,
permissions: false,
analytics: hasAnalyticsPermission
}
};
case'ANALYTICS_LOADED':
return {
...state,
analytics: action.payload,
loading: { ...state.loading, analytics: false }
};
case'NOTIFICATIONS_LOADED':
return {
...state,
notifications: action.payload,
loading: { ...state.loading, notifications: false }
};
case'ALL_LOADED':
return {
...state,
isInitialized: true
};
case'SET_ERROR':
return {
...state,
error: action.payload,
loading: initialState.loading
};
case'RETRY':
return {
...state,
retryCount: state.retryCount + 1,
error: null
};
default:
return state;
}
}
// 重构后的组件
function OptimizedDashboard({ projectId, userId }) {
const [state, dispatch] = useReducer(dashboardReducer, initialState);
// 核心数据加载逻辑 - 只需要一个useEffect
useEffect(() => {
asyncfunction loadDashboardData() {
try {
dispatch({ type: 'INIT_LOADING' });
// Step 1: 加载项目数据
const projectData = await fetchProjectData(projectId);
dispatch({ type: 'PROJECT_LOADED', payload: projectData });
// Step 2: 并行加载用户数据
const userData = await fetchUserData(userId);
dispatch({ type: 'USER_LOADED', payload: userData });
// Step 3: 加载权限和通知(可并行)
const [permissions, notifications] = awaitPromise.all([
fetchUserPermissions(userId, projectData.id),
fetchNotifications(userId)
]);
dispatch({ type: 'PERMISSIONS_LOADED', payload: permissions });
dispatch({ type: 'NOTIFICATIONS_LOADED', payload: notifications });
// Step 4: 根据权限决定是否加载分析数据
if (permissions.includes('view_analytics')) {
const analytics = await fetchAnalytics(projectId);
dispatch({ type: 'ANALYTICS_LOADED', payload: analytics });
}
dispatch({ type: 'ALL_LOADED' });
} catch (error) {
dispatch({ type: 'SET_ERROR', payload: error });
}
}
loadDashboardData();
}, [projectId, userId, state.retryCount]);
// 自动重试逻辑
useEffect(() => {
if (state.error && state.retryCount < 3) {
const timer = setTimeout(() => {
dispatch({ type: 'RETRY' });
}, 2000 * Math.pow(2, state.retryCount));
return() => clearTimeout(timer);
}
}, [state.error, state.retryCount]);
return (
<div>
{state.isInitialized ? (
<DashboardContent {...state} />
) : (
<LoadingIndicator loading={state.loading} />
)}
</div>
);
}
性能提升分析渲染减少:约65%
内存减少:约40%
// 高级数据获取Hook
function useDashboardData(projectId, userId, options = {}) {
const {
enableRetry = true,
maxRetries = 3,
retryDelay = 2000,
enableCache = true
} = options;
const [state, setState] = useState({
data: {
project: null,
user: null,
permissions: [],
analytics: null,
notifications: []
},
meta: {
isLoading: false,
isInitialized: false,
loadingProgress: 0,
error: null,
retryCount: 0,
lastUpdated: null
}
});
// 缓存机制
const cacheKey = useMemo(() =>`${projectId}-${userId}`, [projectId, userId]);
const cache = useRef(newMap());
// 数据加载函数
const loadData = useCallback(async () => {
// 检查缓存
if (enableCache && cache.current.has(cacheKey)) {
const cachedData = cache.current.get(cacheKey);
const cacheAge = Date.now() - cachedData.timestamp;
if (cacheAge < 300000) { // 5分钟缓存
setState(prev => ({
data: cachedData.data,
meta: {
...prev.meta,
isLoading: false,
isInitialized: true,
loadingProgress: 100
}
}));
return;
}
}
setState(prev => ({
...prev,
meta: {
...prev.meta,
isLoading: true,
loadingProgress: 0,
error: null
}
}));
try {
// 创建取消令牌
const abortController = new AbortController();
// 步骤1:加载项目数据
const projectData = await fetchProjectData(projectId, {
signal: abortController.signal
});
setState(prev => ({
...prev,
data: { ...prev.data, project: projectData },
meta: { ...prev.meta, loadingProgress: 20 }
}));
// 步骤2:加载用户数据
const userData = await fetchUserData(userId, {
signal: abortController.signal
});
setState(prev => ({
...prev,
data: { ...prev.data, user: userData },
meta: { ...prev.meta, loadingProgress: 40 }
}));
// 步骤3:并行加载权限和通知
const [permissions, notifications] = awaitPromise.all([
fetchUserPermissions(userId, projectData.id, {
signal: abortController.signal
}),
fetchNotifications(userId, {
signal: abortController.signal
})
]);
setState(prev => ({
...prev,
data: {
...prev.data,
permissions,
notifications
},
meta: { ...prev.meta, loadingProgress: 70 }
}));
// 步骤4:条件性加载分析数据
let analytics = null;
if (permissions.includes('view_analytics')) {
analytics = await fetchAnalytics(projectId, {
signal: abortController.signal
});
}
const finalData = {
project: projectData,
user: userData,
permissions,
analytics,
notifications
};
// 更新缓存
if (enableCache) {
cache.current.set(cacheKey, {
data: finalData,
timestamp: Date.now()
});
}
setState({
data: finalData,
meta: {
isLoading: false,
isInitialized: true,
loadingProgress: 100,
error: null,
retryCount: 0,
lastUpdated: newDate()
}
});
return() => abortController.abort();
} catch (error) {
if (error.name !== 'AbortError') {
setState(prev => ({
...prev,
meta: {
...prev.meta,
isLoading: false,
error,
retryCount: prev.meta.retryCount + 1
}
}));
}
}
}, [projectId, userId, cacheKey, enableCache]);
// 自动重试逻辑
useEffect(() => {
if (state.meta.error && enableRetry && state.meta.retryCount < maxRetries) {
const timer = setTimeout(() => {
loadData();
}, retryDelay * Math.pow(2, state.meta.retryCount - 1));
return() => clearTimeout(timer);
}
}, [state.meta.error, state.meta.retryCount, enableRetry, maxRetries, retryDelay, loadData]);
// 初始化数据加载
useEffect(() => {
loadData();
}, [loadData]);
// 手动刷新函数
const refresh = useCallback(() => {
if (enableCache) {
cache.current.delete(cacheKey);
}
setState(prev => ({
...prev,
meta: { ...prev.meta, retryCount: 0 }
}));
loadData();
}, [loadData, cacheKey, enableCache]);
return {
...state.data,
...state.meta,
refresh
};
}
// 使用优化后的Hook
function SuperOptimizedDashboard({ projectId, userId }) {
const {
project,
user,
permissions,
analytics,
notifications,
isLoading,
isInitialized,
loadingProgress,
error,
refresh
} = useDashboardData(projectId, userId, {
enableRetry: true,
maxRetries: 3,
enableCache: true
});
if (!isInitialized) {
return<ProgressIndicator progress={loadingProgress} />;
}
if (error) {
return<ErrorBoundary error={error} onRetry={refresh} />;
}
return (
<DashboardLayout>
<ProjectSection data={project} />
<UserSection data={user} />
{permissions.includes('view_analytics') && (
<AnalyticsSection data={analytics} />
)}
<NotificationsSection data={notifications} />
</DashboardLayout>
);
}
优化策略三:状态机模式处理复杂交互// 定义状态机配置
const dashboardStateMachine = {
idle: {
on: {
LOAD_START: 'loading',
REFRESH: 'refreshing'
}
},
loading: {
on: {
LOAD_SUCCESS: 'loaded',
LOAD_ERROR: 'error',
LOAD_CANCEL: 'idle'
}
},
loaded: {
on: {
REFRESH: 'refreshing',
UPDATE_DATA: 'updating',
LOAD_ERROR: 'error'
}
},
refreshing: {
on: {
LOAD_SUCCESS: 'loaded',
LOAD_ERROR: 'error',
LOAD_CANCEL: 'loaded'
}
},
updating: {
on: {
UPDATE_SUCCESS: 'loaded',
UPDATE_ERROR: 'error'
}
},
error: {
on: {
RETRY: 'loading',
RESET: 'idle'
}
}
};
function useStateMachine(initialState, stateMachine) {
const [currentState, setCurrentState] = useState(initialState);
const [context, setContext] = useState({});
const transition = useCallback((event, payload = {}) => {
setCurrentState(prevState => {
const nextState = stateMachine[prevState]?.on?.[event];
if (nextState) {
setContext(payload);
return nextState;
}
return prevState;
});
}, [stateMachine]);
const is = useCallback((state) => currentState === state, [currentState]);
const can = useCallback((event) => {
return !!stateMachine[currentState]?.on?.[event];
}, [currentState, stateMachine]);
return { state: currentState, context, transition, is, can };
}
// 使用状态机的组件
function StateMachineDashboard({ projectId, userId }) {
const { state, context, transition, is, can } = useStateMachine('idle', dashboardStateMachine);
const [data, setData] = useState({});
const loadData = useCallback(async () => {
if (!can('LOAD_START') && !can('REFRESH') && !can('RETRY')) return;
const isRefresh = is('loaded');
transition(isRefresh ? 'REFRESH' : 'LOAD_START');
try {
// 数据加载逻辑
const result = await loadDashboardData(projectId, userId);
setData(result);
transition('LOAD_SUCCESS', { lastUpdated: newDate() });
} catch (error) {
transition('LOAD_ERROR', { error });
}
}, [projectId, userId, can, is, transition]);
useEffect(() => {
if (is('idle')) {
loadData();
}
}, [is, loadData]);
const handleRetry = () => {
if (can('RETRY')) {
transition('RETRY');
loadData();
}
};
const handleRefresh = () => {
if (can('REFRESH')) {
loadData();
}
};
return (
<div>
{is('loading') && <LoadingSpinner />}
{is('refreshing') && <RefreshIndicator />}
{is('error') && (
<ErrorDisplay
error={context.error}
onRetry={handleRetry}
canRetry={can('RETRY')}
/>
)}
{is('loaded') && (
<DashboardContent
data={data}
onRefresh={handleRefresh}
canRefresh={can('REFRESH')}
lastUpdated={context.lastUpdated}
/>
)}
</div>
);
}
React 18并发特性的深度集成function useConcurrentDashboardData(projectId, userId) {
const [isPending, startTransition] = useTransition();
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const deferredProjectId = useDeferredValue(projectId);
const deferredUserId = useDeferredValue(userId);
useEffect(() => {
startTransition(async () => {
try {
setError(null);
const result = await loadDashboardData(deferredProjectId, deferredUserId);
setData(result);
} catch (err) {
setError(err);
}
});
}, [deferredProjectId, deferredUserId]);
return { data, error, isPending };
}
// Suspense集成
function SuspenseDashboard({ projectId, userId }) {
return (
<Suspense fallback={<DashboardSkeleton />}>
<ErrorBoundary>
<DashboardContent projectId={projectId} userId={userId} />
</ErrorBoundary>
</Suspense>
);
}
性能基准测试与对比分析Cumulative Layout Shift 0.15 0.04 73.3%
useEffect(() => {
const handleResize = () => setWindowSize(window.innerWidth);
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
2.第三方库集成useEffect(() => {
const chart = new Chart(canvasRef.current, config);
return () => chart.destroy();
}, []);
3.订阅和清理useEffect(() => {
const subscription = eventBus.subscribe('user-updated', handleUserUpdate);
return () => subscription.unsubscribe();
}, []);
❌ 应该避免使用useEffect的场景:// 不好的做法
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
// 更好的做法
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const fullName = `${firstName} ${lastName}`;
2.复杂的异步状态管理// 不好的做法 - 多个useEffect处理相关状态
useEffect(() => { /* 获取用户数据 */ }, [userId]);
useEffect(() => { /* 获取权限数据 */ }, [userData]);
useEffect(() => { /* 处理加载状态 */ }, [userData, permissions]);
// 更好的做法 - 使用自定义Hook或useReducer
const { userData, permissions, isLoading } = useUserData(userId);
性能优化决策树开始
↓
是否需要处理副作用?
├─ 是 → 使用useEffect
└─ 否 ↓
是否有多个相关的状态需要同时更新?
├─ 是 → 考虑useReducer
└─ 否 ↓
是否需要复杂的异步逻辑?
├─ 是 → 创建自定义Hook
└─ 否 ↓
是否有复杂的状态转换?
├─ 是 → 考虑状态机模式
└─ 否 → 使用简单的useState
渐进式重构策略.设置代码审查检查点