挑战21天手写前端框架 day8 基于新版 react-router 实现前端路由与 SPA

简介: 挑战21天手写前端框架 day8 基于新版 react-router 实现前端路由与 SPA

image.png


阅读本文需要 5 分钟,编写本文耗时 1 小时


经过一周的努力,我们已经完成了前端框架的工程化的基础部分,完成了一个能跑的前端框架工程。接下来我们会将需求实现转移到项目交付本身相关的内容上来。


SPA

SPA 就是单页面 Web 应用,顾名思义就是只有一个页面,所有的用户访问都在这个页面中进行,只有一开始的时候加载了需要的 javascript 和 css 之后。(不考虑按需加载优化等情况的时候)用户的操作都将在当前页面中完成,有前端实现的 javascript 控制整个页面的交互逻辑。


有个比较容易分辨是否是 SPA 的方法,是当你在页面中发生“页面跳转”的时候,页面是否重新刷新,重新加载了 js。如果是按需引入添加的 js 请求,是在你现有的基础上而外发起的请求,原来已加载的请求不会刷新。



为什么现在基本上都选择使用 SPA

除了部分比较传统的网站,有强烈 SEO 优化需求的项目之外,现在前端首选几乎都是 SPA。因为它除了首次加载页面耗时之外,其他的用户交互体验都比多页应用要快,部分内容的更改,不需要整个页面的刷新。前端的渲染也不用占用服务器资源。所以从用户体验和成本上来说,SPA 都是 Web 2.0 之后较好的选择。


react-router

React Router 是 React 的一个功能齐全的客户端和服务器端路由库,它是一个用于构建用户界面的 JavaScript库。React Router 可以运行在 React 运行的任何地方;在web上的实现是 react-router-dom。


react-router@6 api

react-router@6 与 react-router@5 存在一定的差异,包含导出组件和导出 api 的使用,这在掘金上有很多的文章介绍,这里就不做过多的展开,我只罗列了本次文章中我们会使用到的几个简单的 api。

导出 作用 说明
<Routes> 一组路由 所有子路由都用基础的 Router 来表示,必须写
<Route> 基础路由 Route 是可以嵌套的
<Link> 导航组件 在实际页面中跳转使用
<Outlet/> 自适应渲染组件,你可以把它当作之前的 children 根据实际路由 url 自动选择组件
useLocation 返回当前的location 对象 -

react-router@6 更新最让我惊喜的是 Outlet 组件,他还有一个配套的 useLocation hooks 供用户使用,用它来实现 keepalive 功能,比之前的实现要优雅简单的多,明天我们的主题就是手写一个 keepalive 组件。



在项目中配置路由

安装依赖

cd examples/app
pnpm i react-router react-router-dom
复制代码

记得安装两个依赖 react-routerreact-router-dom,使用的时候,我们只从 react-router-dom 中使用它导出的 API。 react-routerreact-router-dom 的核心包,所以它是必须安装的。


在项目中使用

examples/app/src/index.ts

首先我们先改一下我们页面的渲染入口组件。

const App = () => {
    return ();
}
const root = ReactDOM.createRoot(document.getElementById('malita'));
- root.render(React.createElement(Hello));
+ root.render(React.createElement(App));
复制代码


编写我们的 app 组件

const App = () => {
    return (
        <HashRouter>
            <Routes>
                <Route path='/' element={<Layout />}>
                    <Route path="/" element={<Hello />} />
                    <Route path="/users" element={<Users />} />
                    <Route path="/me" element={<Me />} />
                </Route>
            </Routes>
        </HashRouter>
    );
}
复制代码


仔细看上述的实现,我们使用 Route 嵌套了 Route 组件,这将会导致在渲染内层 Route 组件是会用外层的 Route 包裹,说起来有一点绕,简单的说就是常常被提到的 layout 功能。


实现 layout 页面,layout 就是多个页面的公共部分的提取,这包括公共部分页面也包括公共逻辑和数据流。

比如,你可以编写一个仅仅处理逻辑的 layout 页面。

import { Outlet, useLocation } from 'react-router-dom';
const Layout = () => {
    const { pathname } = useLocation();
    console.log(pathname);
    return (<Outlet />);
}
复制代码


下面我们简单的编写一个我们本次教程需要的 layout 吧。 就是返回被嵌套的内部 Route 的渲染,简单理解就是之前的 {children}

import { Outlet, useLocation } from 'react-router-dom';
import { Page, Content, Header } from '@alita/flow';
const Layout = () => {
    const { pathname } = useLocation();
    return (<Page>
        <Header>当前路由: {pathname}</Header>
        <Content>
            <Outlet />
        </Content>
    </Page>)
}
复制代码


简单的编写一下三个页面的组件,值得注意的是,我们使用 Link 组件来做页面跳转,他的功能就相当于元素上添加一个 onClick 事件,响应的是 history.push(to);


const Hello = () => {
    const [text, setText] = React.useState('Hello Malita!');
    return (
        <>
            <p
                onClick={() => {
                    setText('Hi!')
                }}> {text} </p>
            <Link to='/users'>Users</Link>
        </>);
};
const Users = () => {
    return (
        <>
            <p> Users </p>
            <Link to='/me'>Me</Link>
        </>);
};
const Me = () => {
    return (<><p> Me </p> <Link to='/'>go Home</Link></>);
};
复制代码


上面的代码对于对 React Router 比较熟悉的朋友应该看一眼就清楚了,对于 React Router 不熟悉的朋友感兴趣的话可以再过一下官网的新手教程

因为在 malita 的设计中,我们会弱化掉这个概念,后续会沿用 umi 中的“文件即路由”的思路,毕竟这是我最喜欢的一个特性,所以你没有掌握 react-router 的知识,也可以正常继续后续的开发工作。



效果展示

image.png

仔细观察上面的操作,我们在进行页面切换的时候,页面并没有发生刷新。


感谢阅读,今天的内容比较简单,仅仅作为对 react-router 的一个简单应用,同时作为明天 keepalive 实现的一个前置预告。因为路由部分是我们实现 keepalive 的基础。如果你对 react 状态保持感兴趣,在 react 官方支持这个功能之前,有强烈需求的,可以关注一下明天的文章内容。


源码归档

目录
相关文章
|
3月前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
107 9
|
4月前
|
前端开发
深入解析React Hooks:构建高效且可维护的前端应用
本文将带你走进React Hooks的世界,探索这一革新特性如何改变我们构建React组件的方式。通过分析Hooks的核心概念、使用方法和最佳实践,文章旨在帮助你充分利用Hooks来提高开发效率,编写更简洁、更可维护的前端代码。我们将通过实际代码示例,深入了解useState、useEffect等常用Hooks的内部工作原理,并探讨如何自定义Hooks以复用逻辑。
|
3月前
|
监控 前端开发 数据可视化
3D架构图软件 iCraft Editor 正式发布 @icraft/player-react 前端组件, 轻松嵌入3D架构图到您的项目,实现数字孪生
@icraft/player-react 是 iCraft Editor 推出的 React 组件库,旨在简化3D数字孪生场景的前端集成。它支持零配置快速接入、自定义插件、丰富的事件和方法、动画控制及实时数据接入,帮助开发者轻松实现3D场景与React项目的无缝融合。
248 8
3D架构图软件 iCraft Editor 正式发布 @icraft/player-react 前端组件, 轻松嵌入3D架构图到您的项目,实现数字孪生
|
3月前
|
前端开发 JavaScript 开发者
使用React和Redux构建高效的前端应用
使用React和Redux构建高效的前端应用
66 1
|
4月前
|
前端开发 数据管理 编译器
引领前端未来:React 19的重大更新与实战指南🚀
React 19 即将发布,带来一系列革命性的新功能,旨在简化开发过程并显著提升性能。本文介绍了 React 19 的核心功能,如自动优化重新渲染的 React 编译器、加速初始加载的服务器组件、简化表单处理的 Actions、无缝集成的 Web 组件,以及文档元数据的直接管理。这些新功能通过自动化、优化和增强用户体验,帮助开发者构建更高效的 Web 应用程序。
247 1
引领前端未来:React 19的重大更新与实战指南🚀
|
3月前
|
前端开发 JavaScript Android开发
前端框架趋势:React Native在跨平台开发中的优势与挑战
【10月更文挑战第27天】React Native 是跨平台开发领域的佼佼者,凭借其独特的跨平台能力和高效的开发体验,成为许多开发者的首选。本文探讨了 React Native 的优势与挑战,包括跨平台开发能力、原生组件渲染、性能优化及调试复杂性等问题,并通过代码示例展示了其实际应用。
89 2
|
3月前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】React与Vue:前端框架的巅峰对决与选择策略
|
3月前
|
前端开发 JavaScript 开发者
“揭秘React Hooks的神秘面纱:如何掌握这些改变游戏规则的超能力以打造无敌前端应用”
【10月更文挑战第25天】React Hooks 自 2018 年推出以来,已成为 React 功能组件的重要组成部分。本文全面解析了 React Hooks 的核心概念,包括 `useState` 和 `useEffect` 的使用方法,并提供了最佳实践,如避免过度使用 Hooks、保持 Hooks 调用顺序一致、使用 `useReducer` 管理复杂状态逻辑、自定义 Hooks 封装复用逻辑等,帮助开发者更高效地使用 Hooks,构建健壮且易于维护的 React 应用。
50 2
|
3月前
|
前端开发 JavaScript 数据管理
React与Vue:两大前端框架的较量与选择策略
【10月更文挑战第23天】React与Vue:两大前端框架的较量与选择策略
|
3月前
|
前端开发 JavaScript 算法
探索现代前端框架——React 的性能优化策略
探索现代前端框架——React 的性能优化策略
35 0