Web学习笔记-React(路由)

这篇具有很好参考价值的文章主要介绍了Web学习笔记-React(路由)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

笔记内容转载自 AcWing 的 Web 应用课讲义,课程链接:AcWing Web 应用课。

本节内容是如何将页面和 URL 一一对应起来。

1. Web分类

Web 页面可以分为两大类:

  • 静态页面:页面里的数据是写死的,即整个文件存放在服务器上,当用户访问 URL 时,服务器原封不动地将页面信息传给前端。
  • 动态页面:页面里的数据是动态填充的,即服务器上存的是页面的模板数据是存到数据库里的,当用户打开页面时,会动态将这个页面拼接起来。现在一般都是动态页面。
    • 后端渲染:数据在后端填充,即模板与数据的拼接操作是在服务器端进行的。客户端向服务器端发送 URL,服务器端返回拼接好的页面。
    • 前端渲染:数据在前端填充,即模板与数据的拼接操作是在用户的浏览器进行的。第一次打开页面时,客户端向服务器端发送 URL,服务器端返回所有页面的模板,渲染的时候根据当前需要哪些数据再向服务器端请求数据;第二次打开页面时,直接用 JS 刷新当前页面,不一定会向后端发送请求。

2. Route组件

Route 组件可以让我们的前端页面也可以和 URL 唯一对应起来,使得前端渲染的模式看起来假装和后端渲染是一样的。

我们创建一个新的项目 route-app,然后用 VS Code 打开项目:

create-react-app route-app

配置一下环境:

  • VS Code 安装插件:Auto Import - ES6, TS, JSX, TSX
  • 安装 Route 组件(在项目根目录下安装,安装好后重启一下 VS Code):npm i react-router-dom
  • 安装 Bootstrap:npm i bootstrap

Route 组件介绍:

  • BrowserRouter:所有需要路由的组件,都要包裹在 BrowserRouter 组件内;
  • Link:跳转到某个链接(但是没有向后端发请求),to 属性表示跳转到的链接;
  • Routes:类似于 C++ 中的 switch,但是只匹配第一个路径,即从前往后看每个 Route,判断当前链接是否等于 Route 中的链接,如果是则渲染 Route 中的组件,之后的就不继续往下判断了;
  • Route:路由,path 属性表示路径,element 属性表示路由到的内容(组件)。

我们先创建好我们项目的根组件 App、导航栏 NavBar,以及多个子页面的组件:HomeLinuxDjangoWebNotFound

NavBar 代码如下:

import React, { Component } from 'react';

class NavBar extends Component {
    state = {  } 
    render() {
        return (
            <nav className="navbar navbar-expand-lg bg-body-tertiary">
                <div className="container-fluid">
                    <a className="navbar-brand" href="/">讲义</a>
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                    <span className="navbar-toggler-icon"></span>
                    </button>
                    <div className="collapse navbar-collapse" id="navbarNavAltMarkup">
                        <div className="navbar-nav">
                            <a className="nav-link active" aria-current="page" href="/">Home</a>
                            <a className="nav-link" href="/linux">Linux</a>
                            <a className="nav-link" href="/django">Django</a>
                            <a className="nav-link" href="/web">Web</a>
                        </div>
                    </div>
                </div>
            </nav>
        );
    }
}

export default NavBar;

App 代码如下:

import React, { Component } from 'react';
import NavBar from './navbar';
import Home from './home';
import Linux from './linux';
import Django from './django';
import Web from './web';
import NotFound from './notfound';

class App extends Component {
    state = {  } 
    render() {
        return (
            <React.Fragment>
                <NavBar />
            </React.Fragment>
        );
    }
}

export default App;

HomeLinuxDjangoWebNotFound 代码类似,只展示一个:

import React, { Component } from 'react';

class Home extends Component {
    state = {  } 
    render() {
        return (
            <h1>Home</h1>
        );
    }
}

export default Home;

现在我们根据 URL 来渲染页面,注意此时还是属于后端渲染,每次都会重新加载页面,我们修改 App

import React, { Component } from 'react';
import NavBar from './navbar';
import Home from './home';
import Linux from './linux';
import Django from './django';
import Web from './web';
import NotFound from './notfound';
import { Routes, Route } from 'react-router-dom'

class App extends Component {
    state = {  } 
    render() {
        return (
            <React.Fragment>
                <NavBar />
                <Routes>  // 一定要将路由包含在Routes里面,里面会有很多个Route
                    <Route path='/' element={<Home />} />  // 如果链接为'/'就跳到Home组件
                    <Route path='/linux' element={<Linux />} />
                    <Route path='/django' element={<Django />} />
                    <Route path='/web' element={<Web />} />
                </Routes>
            </React.Fragment>
        );
    }
}

export default App;

现在我们用 Link 替换 NavBar 中的链接标签 a,这样就变为了前端渲染:

import React, { Component } from 'react';
import { Link } from 'react-router-dom'

class NavBar extends Component {
    state = {  } 
    render() {
        return (
            <nav className="navbar navbar-expand-lg bg-body-tertiary">
                <div className="container-fluid">
                    <Link className="navbar-brand" to="/">讲义</Link>
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
                    <span className="navbar-toggler-icon"></span>
                    </button>
                    <div className="collapse navbar-collapse" id="navbarNavAltMarkup">
                        <div className="navbar-nav">
                            <Link className="nav-link" aria-current="page" to="/">Home</Link>
                            <Link className="nav-link" to="/linux">Linux</Link>
                            <Link className="nav-link" to="/django">Django</Link>
                            <Link className="nav-link" to="/web">Web</Link>
                        </div>
                    </div>
                </div>
            </nav>
        );
    }
}

export default NavBar;

3. URL中传递参数

当网站的页面数量很多的时候,我们肯定不可能去写那么多个 Route

假设我们现在有几篇 Web 讲义,第 i i i 篇的路由链接为:/web/content/i

import React, { Component } from 'react';
import { Link } from 'react-router-dom'

class Web extends Component {
    state = {
        webs: [
            {id: 1, title: 'HTML基础标签'},
            {id: 2, title: 'CSS'},
            {id: 3, title: 'JavaScript'},
            {id: 4, title: '中期项目-拳皇'},
            {id: 5, title: 'React'},
        ]
    } 
    render() {
        return (
            <React.Fragment>
                <h1>Web</h1>
                <hr />
                <div>
                    {this.state.webs.map(web => (
                        <div key={web.id}>
                            <Link to={`/web/content/${web.id}`}>{web.id + '.' + web.title}</Link>
                        </div>
                    ))}
                </div>
            </React.Fragment>
        );
    }
}

export default Web;

我们先实现一下讲义内容的组件 WebContent

import React, { Component } from 'react';

class WebContent extends Component {
    state = {  } 
    render() {
        return (
            <h1>Web Content</h1>
        );
    }
}

export default WebContent;

然后在 App 中写一下路由(我们不能写多个 <Route path='/web/content/i' element={<WebContent />} />,而是用 :xxx):

import React, { Component } from 'react';
import NavBar from './navbar';
import Home from './home';
import Linux from './linux';
import Django from './django';
import Web from './web';
import WebContent from './webcontent';
import NotFound from './notfound';
import { Routes, Route } from 'react-router-dom'

class App extends Component {
    state = {  } 
    render() {
        return (
            <React.Fragment>
                <NavBar />
                <div className='container'>
                    <Routes>  // 一定要将路由包含在Routes里面,里面会有很多个Route
                        <Route path='/' element={<Home />} />  // 如果链接为'/'就跳到Home组件
                        <Route path='/linux' element={<Linux />} />
                        <Route path='/django' element={<Django />} />
                        <Route path='/web' element={<Web />} />
                        <Route path='/web/content/:chapter' element={<WebContent />} />
                    </Routes>
                </div>
            </React.Fragment>
        );
    }
}

export default App;

现在我们如何在 WebContent 中获取 :chapter 参数呢?先看一下函数组件获取参数的方式,可以直接用 useParams 函数获取参数:

import React from 'react';
import { useParams } from 'react-router-dom';

const WebContent = () => {
    console.log(useParams())
    return (
        <h1>Web Content - {useParams().chapter}</h1>
    );
}

export default WebContent;

如果是类组件的话就需要先套一层函数组件,然后把 useParams 函数作为参数传给自己:

import React, { Component } from 'react';
import { useParams } from 'react-router-dom';

class WebContent extends Component {
    state = {  } 
    render() {
        console.log(this.props.params)
        return (
            <h1>Web Content - {this.props.params.chapter}</h1>
        );
    }
}

export default (props) => (
    <WebContent
        {...props}  // 先把函数组件里面的属性展开
        params={useParams()}
    />
);

4. Search Params传递参数

如果网站链接形式为:/web/content?chapter=3,这样的链接也可以获取参数。

我们先改一下 Web 中的链接形式:

import React, { Component } from 'react';
import { Link } from 'react-router-dom'

class Web extends Component {
    state = {
        webs: [
            ...
        ]
    } 
    render() {
        return (
            <React.Fragment>
                <h1>Web</h1>
                <hr />
                <div>
                    {this.state.webs.map(web => (
                        <div key={web.id}>
                            <Link to={`/web/content?chapter=${web.id}`}>{web.id + '.' + web.title}</Link>
                        </div>
                    ))}
                </div>
            </React.Fragment>
        );
    }
}

export default Web;

然后在 WebContent 中获取链接的参数:

import React, { Component } from 'react';
import { useSearchParams } from 'react-router-dom';
import { Link } from 'react-router-dom'

class WebContent extends Component {
    state = {
        searchParams: this.props.params[0],  // 用于获取某一个参数
        setSearchParams: this.props.params[1],  // 用于设置链接里的参数,重新渲染页面
    };
    render() {
        console.log(this.state.searchParams.get('chapter'))
        return (
            <React.Fragment>
                <h1>Web Content - {this.state.searchParams.get('chapter')}</h1>
                <hr />
                <div>讲义内容</div>
                <hr />
                <Link to='/web'>返回上一级</Link>
            </React.Fragment>
        );
    }
}

export default (props) => (
    <WebContent
        {...props}  // 先把函数组件里面的属性展开
        params={useSearchParams()}
    />
);

函数组件的写法如下:

import React from 'react';
import { useSearchParams } from 'react-router-dom';
import { Link } from 'react-router-dom'

const WebContent = () => {
    let [searchParams, setSearchParams] = useSearchParams();
    console.log(searchParams.get('chapter'));
    return (
        <React.Fragment>
            <h1>Web Content - {searchParams.get('chapter')}</h1>
            <hr />
            <div>讲义内容</div>
            <hr />
            <Link to='/web'>返回上一级</Link>
        </React.Fragment>
    );
}

export default WebContent;

5. 重定向

当打开一个不存在的链接时应该重定向到 404 Not Found,我们先将这个路由定义出来:<Route path='/404' element={<NotFound />} />

使用 Navigate 组件可以重定向,我们可以使用通配符 * 匹配其余的所有路径,然后将其重定向到 /404 页面即可:

import React, { Component } from 'react';
import NavBar from './navbar';
import Home from './home';
import Linux from './linux';
import Django from './django';
import Web from './web';
import WebContent from './webcontent';
import NotFound from './notfound';
import { Routes, Route, Navigate } from 'react-router-dom'

class App extends Component {
    state = {  } 
    render() {
        return (
            <React.Fragment>
                <NavBar />
                <div className='container'>
                    <Routes>  // 一定要将路由包含在Routes里面,里面会有很多个Route
                        <Route path='/' element={<Home />} />  // 如果链接为'/'就跳到Home组件
                        <Route path='/linux' element={<Linux />} />
                        <Route path='/django' element={<Django />} />
                        <Route path='/web' element={<Web />} />
                        <Route path='/web/content' element={<WebContent />} />
                        <Route path='/404' element={<NotFound />} />
                        <Route path='*' element={<Navigate replace to='/404' />} />
                    </Routes>
                </div>
            </React.Fragment>
        );
    }
}

export default App;

6. 嵌套路由

假设 Linux 组件中有两个子模块 HomeworkTerminal,我们可以在 App 中创建嵌套路由:

import React, { Component } from 'react';
import NavBar from './navbar';
import Home from './home';
import Linux from './linux';
import Django from './django';
import Web from './web';
import WebContent from './webcontent';
import NotFound from './notfound';
import { Routes, Route, Navigate } from 'react-router-dom'

class App extends Component {
    state = {  } 
    render() {
        return (
            <React.Fragment>
                <NavBar />
                <div className='container'>
                    <Routes>  // 一定要将路由包含在Routes里面,里面会有很多个Route
                        <Route path='/' element={<Home />} />  // 如果链接为'/'就跳到Home组件
                        <Route path='/linux' element={<Linux />}>
                            <Route path='homework' element={<h4>Homework</h4>} />
                            <Route path='terminal' element={<h4>Terminal</h4>} />
                        </Route>
                        <Route path='/django' element={<Django />} />
                        <Route path='/web' element={<Web />} />
                        <Route path='/web/content' element={<WebContent />} />
                        <Route path='/404' element={<NotFound />} />
                        <Route path='*' element={<Navigate replace to='/404' />} />
                    </Routes>
                </div>
            </React.Fragment>
        );
    }
}

export default App;

但是现在执行网页 /linux/homework 时不会渲染出子路由的内容,我们需要在父组件中添加 <Outlet /> 组件,用来填充子组件的内容:文章来源地址https://www.toymoban.com/news/detail-705926.html

import React, { Component } from 'react';
import { Link, Outlet } from 'react-router-dom'

class Linux extends Component {
    state = {  } 
    render() {
        return (
            <React.Fragment>
                <h1>Linux</h1>
                <hr />

                <ul className="nav justify-content-center">
                <li className="nav-item">
                    <Link className="nav-link" to="/linux/homework">Homework</Link>
                </li>
                <li className="nav-item">
                    <Link className="nav-link" to="/linux/terminal">Terminal</Link>
                </li>
                </ul>
                <hr />

                <Outlet />
            </React.Fragment>
        );
    }
}

export default Linux;

到了这里,关于Web学习笔记-React(路由)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 简介:在这篇教程中,我们将使用React.js框架创建一个简单的聊天机器人的前端界面,并利用Dialogflo

    作者:禅与计算机程序设计艺术 介绍及动机 聊天机器人(Chatbot)一直是互联网领域中的热门话题。而很多聊天机器人的功能都依赖于人工智能(AI)技术。越来越多的企业希望拥有自己的聊天机器人系统,从而提升自己的竞争力。为此,业界也出现了很多基于开源技术或云

    2024年02月06日
    浏览(42)
  • React学习笔记(番外一)——video.js视频播放组件的入门及排坑经历

    很久没有静下心写博客了。近段时间接到一个任务,前端页面要加上视频播放功能。实现加排坑前后花了三天时间(别问我问什么这么久😂),觉得还是有必要记录一下的。 这一部分有必要写在最前面,避免你看了一长串安装、引入、代码,然后发现自己想要播放的视频格

    2024年02月02日
    浏览(38)
  • React笔记(六)React路由

    一、React路由简介 React 官方并没有提供对应的路由插件,因此,我们需要下载第三方的路由插件 —— React Router DOM。 React Router 在 2021 年 11 月份的时候更新 v6 的版本。本次课就主要讲解V6版本 二、路由配置 1、下载路由 在项目根目录中,通过以下命令 2、路由配置 1)首先在

    2024年02月10日
    浏览(35)
  • 前端框架 Nextjs React 部署

    目录 一、node环境部署 二、静态导出 补充:路由问题 Nextjs打包还是非常方便的,就是网上资料不太全,导致踩了一些坑,下面是我亲自实践的两种打包方式。 一、node环境部署 这种方式最简单,也比较不容易出错,但部署时服务器需安装有node环境,速度没话说,杠杠的! 构

    2024年02月12日
    浏览(37)
  • Web 前端进阶—— JS 学习笔记

    目录 一、JavaScript提升篇 1、什么是跨域? 2、什么是原型? 3、什么是闭包? 4、如何防抖? 5、TCP的三次握手和四次挥手 6、new 操作符原理 7、事件委托做了什么 8、事件代理是什么 9、Eventloop 10、 如何实现跨域 11、写出原生 Ajax 12、暂时性死区是什么 13 、promise 解决回调陷阱的

    2024年04月26日
    浏览(24)
  • Vue 和 React 前端框架的比较

    本文研究了流行的前端框架 Vue 和 React 之间的区别。通过对它们的学习曲线、视图层处理方式、组件化开发、响应式数据处理方式和生态系统及社区支持进行比较分析,得出了它们在不同方面的优劣和特点。该研究对于开发者在选择合适的前端框架时提供参考。 Vue 是一款由

    2024年02月13日
    浏览(50)
  • React与Vue:前端框架的比较

    在前端开发领域,React和Vue是两个备受瞩目的框架。它们都提供了构建用户界面的强大工具,但它们在实现方式、性能和设计理念上存在一些关键差异。本文将深入探讨这两个框架之间的主要区别。 首先,让我们从数据流的角度来看。在Vue中,数据流是双向的,这意味着组件

    2024年01月20日
    浏览(39)
  • 前端面试:【React】构建现代Web的利器

    嘿,亲爱的React探险家!在前端开发的旅程中,有一个神奇的库,那就是 React 。React是一个用于构建现代Web应用的强大工具,它提供了组件化开发、状态管理、生命周期管理和虚拟DOM等特性,让你的应用开发变得更加高效和愉快。 1. 什么是React? React是一个由Facebook开发和维护

    2024年02月11日
    浏览(43)
  • 前端(七)——React框架的定位与应用场景解析

    😊博主:小猫娃来啦 😊文章核心: React框架的定位与应用场景解析 什么是react? React 是一个由 Facebook 开发的开源 JavaScript库,用于构建用户界面。 于2013年首次发布,并迅速成为前端开发中最受欢迎的框架之一。 在 React 诞生之前,前端开发面临着许多挑战,包括复杂的D

    2024年02月17日
    浏览(30)
  • JavaScript 框架比较:Angular、React、Vue.js

    在 Web 开发领域,JavaScript 提供大量技术栈可供选择。其中最典型的三套组合,分别是 MERN、MEAN 和 MEVN。这些首字母相同的选项各自代表不同的技术加工具组合。为了在这些技术栈中做出明智选择,让我们先从核心组件聊起,再对各自前端框架(React、Angular 和 Vue)进行简化比

    2024年01月20日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包