为什么同级的第二个React Context Provider无法正常生效?
问题成因
你当前使用的React Router v5及更早版本的<Switch>组件存在固定匹配逻辑:仅会渲染第一个与当前路径匹配的直接子元素,且只会读取直接子元素上的path属性做匹配校验。
你将<ClientsContextProvider>、<ProjectsContextProvider>作为<Switch>的直接子元素编写,两个Provider本身没有配置path属性,因此<Switch>会判定第一个子元素<ClientsContextProvider>永久匹配所有路径,永远只渲染该Provider及其内部的/clients相关路由,后面的<ProjectsContextProvider>全程不会被渲染,自然/projects相关路由无法生效,组件树中也不会出现该Provider。
解决方案
共有两种常用实现方案可选:
方案1:给Provider配置对应路由前缀
给每个Context Provider添加对应路由的前缀path属性,让<Switch>可以正确识别匹配规则,判断是否需要渲染该Provider:
<Switch> <ClientsContextProvider path="/clients"> <ProtectedRoute exact path="/clients/:clientId" isAuth={isAuth} component={Client} /> <ProtectedRoute exact path="/clients" isAuth={isAuth} component={Clients} /> </ClientsContextProvider> <ProjectsContextProvider path="/projects"> <ProtectedRoute exact path="/projects" isAuth={isAuth} component={Projects} /> <ProtectedRoute exact path="/projects/:projectId" isAuth={isAuth} component={Project} /> </ProjectsContextProvider> </Switch>
方案2:将Provider嵌套在路由渲染逻辑内
直接把Provider放在对应路由的渲染回调中,不需要修改<Switch>的原有匹配逻辑:
<Switch> <ProtectedRoute exact path="/clients/:clientId" isAuth={isAuth} render={props => ( <ClientsContextProvider> <Client {...props} /> </ClientsContextProvider> )} /> <ProtectedRoute exact path="/clients" isAuth={isAuth} render={props => ( <ClientsContextProvider> <Clients {...props} /> </ClientsContextProvider> )} /> <ProtectedRoute exact path="/projects" isAuth={isAuth} render={props => ( <ProjectsContextProvider> <Projects {...props} /> </ProjectsContextProvider> )} /> <ProtectedRoute exact path="/projects/:projectId" isAuth={isAuth} render={props => ( <ProjectsContextProvider> <Project {...props} /> </ProjectsContextProvider> )} /> </Switch>
如果你使用的是React Router v6版本,直接将Provider嵌套在路由的element属性返回的JSX中即可,逻辑和方案2一致。
内容的提问来源于stack exchange,提问作者joshuaebs
相关产品推荐
相关产品推荐

