You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:47:50