React Route使用三元运算符渲染组件总重定向到首页仅刷新生效怎么办
问题根因
- App组件未订阅用户登录状态变更,
user变量仅在组件初始化时从localStorage读取一次,登录完成后localStorage更新不会触发App组件重新渲染,所以三元判断一直使用初始旧值,导致触发重定向。只有刷新页面时App重新初始化,才会读取最新的localStorage值,符合预期。 - 路由配置中使用
component属性传入内联函数属于错误用法,该属性接收的是组件构造函数,内联函数会导致每次路由变更都卸载重建组件,不仅有性能问题还可能带来状态异常,应该用render属性替代。 - auth reducer的默认分支返回空字符串而非原state,会导致redux状态被意外清空。
修复方案
1. 修复auth reducer
把default分支的返回值改为原state:
export default (state={authData:null},action)=>{ switch(action.type){ case "AUTH": localStorage.setItem("profile",JSON.stringify({...action?.data})); return {...state, authData: action.data, loading: false, errors: null}; case "LOGOUT": localStorage.clear(); return {...state,authData:null}; default: return state; // 原逻辑返回""属于错误写法 } }
2. 改造App.js,订阅redux登录状态,修正路由写法
import React, { useEffect, useState } from 'react'; import Header from './Components/Header'; import Home from './Components/Home'; import Checkout from "./Components/Checkout"; import Payment from "./Components/Payment"; import NewProduct from "./Components/NewProduct"; import OrderSuccess from "./Components/OrderSuccess"; import AddressForm from './Components/AddressForm'; import {BrowserRouter, Switch, Route} from "react-router-dom"; import { Redirect } from 'react-router'; import Login from './Components/Login'; import Orders from "./Components/Orders"; import Account from './Components/Account'; import { useSelector } from 'react-redux'; // 引入useSelector读取redux状态 const App=()=>{ // 从redux拿最新的登录状态,redux更新时会触发App重新渲染 const reduxAuth = useSelector(state => state.auth.authData); // 优先用redux的状态,兜底从localStorage取兼容刷新场景 const user = reduxAuth || JSON.parse(localStorage.getItem("profile")); const defaultRoutes= ()=>{ return( <div> <Header/> <Switch> {/* 把component改为render属性 */} <Route path="/account-settings" exact render={()=>user ? <Account />: <Redirect to="/" />} /> <Route path="/orders" exact render={()=>user ? <Orders /> : <Redirect to="/" />} /> <Route path="/checkout" exact render={()=>user ? <Checkout />: <Redirect to="/" />} /> <Route path="/payment" exact render={()=>user ? <Payment /> : <Redirect to="/" />} /> <Route path="/account-settings/add-new-address" exact render={()=>user?.result ? <AddressForm /> : <Redirect to="/" />} /> <Route path="/" exact component={Home} /> </Switch> </div> ) } return ( <BrowserRouter> <Switch> <Route path="/login" exact render={()=>user ? <Redirect to="/" />:<Login />} /> <Route component={defaultRoutes} /> </Switch> </BrowserRouter> ); } export default App;
内容的提问来源于stack exchange,提问作者Naman Kedia
相关产品推荐
相关产品推荐

