React路由延迟与Navbar代码复用问题求助
React应用优化方案:加载状态控制与导航栏代码冗余处理
需求1:API请求过程中渲染Loading组件,完成后再跳转
修改方案:
通过手动控制路由跳转、添加加载状态管理,阻止默认跳转行为,确保请求完成后再执行页面跳转。
1. 更新App中Login路由的传参
<Route path="login" element={<LoginPage setActiveuser={setActiveuser} setIsloading={setIsloading} isloading={isloading} />} />
2. 重写LoginPage组件逻辑
import { useNavigate } from 'react-router-dom'; function LoginPage({ setActiveuser, setIsloading, isloading }) { const usernameInput = useRef(null); const passwordInput = useRef(null); const navigate = useNavigate(); function submitClick(e) { // 阻止默认跳转行为 e.preventDefault(); const usernameValue = usernameInput.current.value; const passwordValue = passwordInput.current.value; // 开启加载状态 setIsloading(true); const apiUrl = "http://127.0.0.1:8889/api/v1/slitapp"; axios .get(apiUrl) .then((response) => { const { slits } = response.data.data; const foundUser = slits.find((user) => user.username === usernameValue); if (foundUser?.password === passwordValue) { setActiveuser(foundUser); // 验证成功后手动跳转首页 navigate("/homepage"); } else { setActiveuser([]); // 可在此添加登录失败提示逻辑 } }) .catch((error) => { console.error("Error:", error); }) .finally(() => { // 请求结束后关闭加载状态 setIsloading(false); }); } return ( <section className="login_page_section "> {/* 加载状态下渲染Loading组件 */} {isloading && <Loading />} <div className="loginPage" style={{ opacity: isloading ? 0.5 : 1 }}> <h2 className="login_heading">Login</h2> <form> <input className="Login_slitID_input" placeholder="SLitID" type="text" ref={usernameInput} disabled={isloading} /> <input className="Login_password_input" placeholder="Password" type="text" ref={passwordInput} disabled={isloading} /> <button onClick={submitClick} className="login_submit_button" disabled={isloading} > {isloading ? "登录中..." : "submit"} </button> </form> </div> </section> ); } export default LoginPage;
关键优化点:
- 用
button替代NavLink,避免默认跳转行为 - 请求前后切换
isloading状态,控制Loading组件显示 - 加载状态下禁用输入框和按钮,防止重复提交
- 验证成功后通过
useNavigate手动跳转页面
需求2:优化NavbarModule的重复渲染,消除代码冗余
修改方案:
创建布局组件统一管理导航栏,通过嵌套路由让需要显示导航栏的页面自动继承布局。
1. 创建Layout布局组件
import { Outlet } from 'react-router-dom'; import NavbarModule from './NavbarModule'; function Layout() { return ( <> <NavbarModule /> {/* Outlet用于渲染子路由的内容 */} <Outlet /> </> ); } export default Layout;
2. 更新App中的路由结构
function App() { const [activeUser, setActiveuser] = useState([]); const [isloading, setIsloading] = useState(false); return ( <section className="slit-app--section"> <BrowserRouter> <Routes> <Route path="/" element={<Navigate replace to="login" />} /> <Route path="login" element={<LoginPage setActiveuser={setActiveuser} setIsloading={setIsloading} isloading={isloading} />} /> {/* 嵌套路由:所有子路由自动继承Layout中的Navbar */} <Route element={<Layout />}> <Route path="homepage" element={ <> <BillsModule activeUser={activeUser} /> <ExtraFeaturesModule activeUser={activeUser} /> </> } /> <Route path="createbill" element={<CreateBill />} /> </Route> </Routes> </BrowserRouter> </section> ); } export default App;
关键优化点:
- 使用
Outlet组件渲染子路由内容,实现布局复用 - 登录路由独立于布局之外,不会显示导航栏
- 消除了
homepage和createbill路由中重复的NavbarModule代码
内容的提问来源于stack exchange,提问作者Kondaveti Charan
相关产品推荐
相关产品推荐

