面试题答案
一键面试- 使用
React.memo
包裹子组件:- 对于那些只依赖于
props
而不依赖于内部状态或生命周期方法的子组件,可以使用React.memo
进行包裹。React.memo
是一个高阶组件,它会对组件的props
进行浅比较,如果props
没有变化,则不会重新渲染该组件。例如:
const MyComponent = React.memo((props) => { return <div>{props.value}</div>; });
- 对于那些只依赖于
- 精细化 Context 拆分:
- 不要将所有认证相关状态都放在一个大的 Context 中。如果可能,将认证状态拆分成多个更细粒度的 Context。例如,将用户基本信息、权限信息等分别放在不同的 Context 中。这样,只有依赖特定 Context 的组件在其对应状态变化时才会重新渲染。例如:
const UserInfoContext = React.createContext(); const UserPermissionsContext = React.createContext();
- 在 Context.Consumer 中使用
useMemo
:- 当使用
Context.Consumer
来订阅 Context 时,可以在内部使用useMemo
来缓存基于 Context 值的计算结果。这样,只有当 Context 值发生变化且计算结果依赖的值也变化时,才会重新计算。例如:
const MyComponent = () => { const authContext = useContext(AuthContext); const derivedValue = useMemo(() => { // 基于 authContext 进行一些计算 return authContext.user.role === 'admin'? 'admin - specific value' : 'default value'; }, [authContext.user.role]); return <div>{derivedValue}</div>; };
- 当使用
- 使用
shouldComponentUpdate
(类组件):- 如果项目中还有类组件,对于依赖认证状态的类组件,可以通过重写
shouldComponentUpdate
方法来自定义组件的更新逻辑。在方法中,可以对新老props
和state
进行比较,只有当认证状态相关的props
或state
发生变化时才返回true
进行重新渲染。例如:
class MyClassComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { return this.props.authState.isLoggedIn!== nextProps.authState.isLoggedIn; } render() { return <div>{this.props.authState.userName}</div>; } }
- 如果项目中还有类组件,对于依赖认证状态的类组件,可以通过重写
- 使用
useCallback
缓存函数:- 如果将函数作为 Context 值传递,并且该函数会导致依赖组件重新渲染,可以使用
useCallback
来缓存函数。这样,只要依赖项没有变化,函数的引用就不会改变,从而避免不必要的重新渲染。例如:
const MyContext = React.createContext(); const ParentComponent = () => { const authContextValue = { user: { name: 'John' }, updateUser: useCallback((newName) => { // 更新用户逻辑 }, []) }; return ( <MyContext.Provider value={authContextValue}> {/* 子组件 */} </MyContext.Provider> ); };
- 如果将函数作为 Context 值传递,并且该函数会导致依赖组件重新渲染,可以使用