能否以条件渲染方式使用React Context?求优化建议
优化思路与方案
方案一:合并为单一Provider,内部处理授权逻辑
将两个Provider的逻辑合并到一个组件中,通过授权状态控制查询是否执行,并统一生成Context的value,避免拆分多个组件:
// 抽离未授权状态的默认常量,减少重复代码 const UN_AUTHORIZED_DEFAULT = { loading: false, status: '', contracts: [] } as const; export const VerificationStatusProvider: FC = ({ children }) => { const { isAuthenticated } = useUserState(); // 仅当用户已授权时触发查询,符合你提到的库的限制 const { data, isLoading } = useQuery({ queryKey: ['userVerificationStatus'], queryFn: fetchUserVerificationStatus, // 你的查询逻辑函数 enabled: isAuthenticated, initialData: UN_AUTHORIZED_DEFAULT, }); // 用useMemo缓存value,避免不必要的Context重渲染 const contextValue = useMemo(() => { if (!isAuthenticated) { return UN_AUTHORIZED_DEFAULT; } return { loading: isLoading, status: data?.status || '', contracts: data?.contracts || [], }; }, [isAuthenticated, isLoading, data]); return ( <VerificationStatusContext.Provider value={contextValue}> {children} </VerificationStatusContext.Provider> ); };
优势:
- 逻辑集中在一个组件,更易维护和调试
- 避免条件渲染不同Provider带来的组件切换开销
- 通过
enabled控制查询执行,规避库的限制,同时保持代码简洁
方案二:保留双Provider但优化代码结构
如果必须保留两个独立Provider,可以通过抽离公共逻辑、简化条件渲染来优化:
const UN_AUTHORIZED_DEFAULT = { loading: false, status: '', contracts: [] } as const; // 未授权Provider复用常量 const UnAuthStatusProvider: FC = ({ children }) => ( <VerificationStatusContext.Provider value={UN_AUTHORIZED_DEFAULT}> {children} </VerificationStatusContext.Provider> ); // 授权Provider专注于查询逻辑 const AuthVerificationStatusProvider: FC = ({ children }) => { const { data, isLoading } = useQuery({ queryKey: ['userVerificationStatus'], queryFn: fetchUserVerificationStatus, }); const contextValue = useMemo(() => ({ loading: isLoading, status: data?.status || '', contracts: data?.contracts || [], }), [isLoading, data]); return ( <VerificationStatusContext.Provider value={contextValue}> {children} </VerificationStatusContext.Provider> ); }; // 主Provider简化条件判断 export const VerificationStatusProvider: FC = ({ children }) => { const { isAuthenticated } = useUserState(); return isAuthenticated ? ( <AuthVerificationStatusProvider>{children}</AuthVerificationStatusProvider> ) : ( <UnAuthStatusProvider>{children}</UnAuthStatusProvider> ); };
优势:
- 抽离常量消除重复代码
- 每个单一Provider职责更清晰,符合单一原则
- 主Provider的条件渲染更直观易读
额外优化点
- 用
useMemo缓存Context的value,避免因依赖项未变化时的不必要重渲染,提升性能 - 为查询函数和默认值添加类型定义(如果用TypeScript),增强代码健壮性
内容的提问来源于stack exchange,提问作者João Freitas
相关产品推荐
相关产品推荐

