面试题答案
一键面试状态管理机制设计
- 使用useReducer Hook:
useReducer
比useState
更适合管理复杂状态逻辑。对于多个异步操作且有依赖关系的场景,useReducer
可以将状态更新逻辑集中在一个reducer
函数中。- 例如,定义一个初始状态:
const initialState = { asyncOp1Status: 'idle', asyncOp2Status: 'idle', progress: 0, data: null };
- 然后定义
reducer
函数来处理不同的异步操作状态变化:
const reducer = (state, action) => { switch (action.type) { case 'ASYNC_OP1_START': return {...state, asyncOp1Status: 'inProgress' }; case 'ASYNC_OP1_SUCCESS': return {...state, asyncOp1Status: 'completed', progress: state.progress + 0.5 }; case 'ASYNC_OP2_START': return {...state, asyncOp2Status: 'inProgress' }; case 'ASYNC_OP2_SUCCESS': return {...state, asyncOp2Status: 'completed', progress: 1, data: action.payload }; default: return state; } };
- 在组件中使用
useReducer
:
const [state, dispatch] = useReducer(reducer, initialState);
- 利用Context API:
- 如果异步操作涉及多个组件,使用
Context API
可以方便地共享状态。 - 创建一个
Context
:
const AsyncContext = React.createContext();
- 在顶层组件中提供
Context
:
<AsyncContext.Provider value={{ state, dispatch }}> {/* 应用的其他组件 */} </AsyncContext.Provider>
- 在需要的子组件中消费
Context
:
const { state, dispatch } = useContext(AsyncContext);
- 如果异步操作涉及多个组件,使用
性能优化 - 避免不必要的重新渲染
- Memoization:
- 使用React.memo:对于展示进度等纯展示组件,可以使用
React.memo
包裹。它会浅比较组件的props
,如果props
没有变化,组件不会重新渲染。
const ProgressIndicator = React.memo(({ progress }) => { return <div>Progress: {progress * 100}%</div>; });
- 使用useMemo和useCallback:
useMemo
用于缓存计算结果。例如,如果某个异步操作的结果需要进行复杂计算,且计算结果在状态变化时不会改变,可以使用useMemo
。
const processedData = useMemo(() => { // 复杂计算 return state.data && state.data.map(item => item * 2); }, [state.data]);
useCallback
用于缓存函数,避免函数在每次渲染时重新创建。例如,在触发异步操作的函数中使用useCallback
。
const startAsyncOp1 = useCallback(() => { dispatch({ type: 'ASYNC_OP1_START' }); // 执行异步操作 }, [dispatch]);
- 使用React.memo:对于展示进度等纯展示组件,可以使用
- Batch Updates:
- React 18 引入了自动批处理。但在之前版本中,如果需要手动批处理状态更新,可以使用
unstable_batchedUpdates
(在 React DOM 中)。这可以将多个状态更新合并为一次渲染,减少不必要的重新渲染。例如:
import ReactDOM from'react-dom'; ReactDOM.unstable_batchedUpdates(() => { dispatch({ type: 'ASYNC_OP1_SUCCESS' }); dispatch({ type: 'ASYNC_OP2_START' }); });
- React 18 引入了自动批处理。但在之前版本中,如果需要手动批处理状态更新,可以使用