React - BrowserRouter 与 HashRouter、push 模式与 replace 模式、编程式导航、withRouter

一、BrowserRouter 与 HashRouter

1、基本介绍
(1)BrowserRouter
  1. URL 形式:example.com/path

  2. 使用 HTML5 的 History API(pushState、replaceState)

  3. 需要服务器配置,所有路径都返回 index.html,否则刷新会 404

(2)HashRouter
  1. URL 形式:example.com/#/path

  2. 使用 URL 的 hash(#)部分

  3. 无需服务器配置,hash 变化不会向服务器发请求

2、基本使用
  1. 使用 BrowserRouter
js 复制代码
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { BrowserRouter } from "react-router-dom";

// 渲染 App 组件到页面
ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById("root"),
);
  1. 使用 HashRouter
js 复制代码
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { HashRouter } from "react-router-dom";

// 渲染 App 组件到页面
ReactDOM.render(
    <HashRouter>
        <App />
    </HashRouter>,
    document.getElementById("root"),
);

二、push 模式与 replace 模式

1、基本介绍
  1. push 模式(默认):在历史栈中添加新记录,可以点击浏览器后退按钮返回上一页

  2. replace 模式:替换当前历史记录,不添加新记录,点击后退不会回到当前页,直接跳到更早的页面

2、replace 模式演示
(1)page
  1. About 组件
js 复制代码
import React, { Component } from "react";

export default class About extends Component {
    render() {
        return <h3>About Content</h3>;
    }
}
  1. Home 组件
js 复制代码
import React, { Component } from "react";

export default class Home extends Component {
    render() {
        return <h3>Home Content</h3>;
    }
}
(2)main
  1. App 组件
js 复制代码
import React, { Component } from "react";
import { Link, Route } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";

export default class App extends Component {
    render() {
        return (
            <div>
                <h2>React Router Demo</h2>
                <div>
                    <Link replace to="/about">About</Link>
                    <Link replace to="/home">Home</Link>
                </div>
                <div>
                    <Route path="/about" component={About} />
                    <Route path="/home" component={Home} />
                </div>
            </div>
        );
    }
}
  1. index.js
js 复制代码
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { BrowserRouter } from "react-router-dom";

// 渲染 App 组件到页面
ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById("root"),
);

三、编程式导航

1、page
  1. Message 组件
js 复制代码
import React, { Component } from "react";
import { Link, Route } from "react-router-dom";
import Detail from "./Detail";
import News from "./News";
import Tip from "./Tip";

export default class Message extends Component {
    state = {
        messageArr: [
            { id: "01", title: "消息 1" },
            { id: "02", title: "消息 2" },
            { id: "03", title: "消息 3" },
        ],
    };

    pushParamsShow = (id, title) => {
        this.props.history.push(`/message/detail/${id}/${title}`);
    };

    replaceParamsShow = (id, title) => {
        this.props.history.replace(`/message/detail/${id}/${title}`);
    };

    pushSearchShow = (id, title) => {
        this.props.history.push(`/message/news/?id=${id}&title=${title}`);
    };

    replaceSearchShow = (id, title) => {
        this.props.history.replace(`/message/news/?id=${id}&title=${title}`);
    };

    pushStateShow = (id, title) => {
        this.props.history.push({ pathname: "/message/tip", state: { id, title } });
    };

    replaceStateShow = (id, title) => {
        this.props.history.replace({ pathname: "/message/tip", state: { id, title } });
    };

    back = () => {
        this.props.history.goBack();
    };

    forward = () => {
        this.props.history.goForward();
    };

    go = () => {
        this.props.history.go(2);
    };

    render() {
        const { messageArr } = this.state;
        return (
            <div>
                <h3>传递 params 参数</h3>
                <ul>
                    {messageArr.map((msgObj) => {
                        return (
                            <li key={msgObj.id}>
                                <button onClick={() => this.pushParamsShow(msgObj.id, msgObj.title)}>{msgObj.title}(push)</button>
                                <button onClick={() => this.replaceParamsShow(msgObj.id, msgObj.title)}>{msgObj.title}(replace)</button>
                            </li>
                        );
                    })}
                </ul>
                <Route path="/message/detail/:id/:title" component={Detail} />
                <h3>传递 search 参数</h3>
                <ul>
                    {messageArr.map((msgObj) => {
                        return (
                            <li key={msgObj.id}>
                                <button onClick={() => this.pushSearchShow(msgObj.id, msgObj.title)}>{msgObj.title}(push)</button>
                                <button onClick={() => this.replaceSearchShow(msgObj.id, msgObj.title)}>{msgObj.title}(replace)</button>
                            </li>
                        );
                    })}
                </ul>
                <Route path="/message/news" component={News} />
                <h3>传递 state 参数</h3>
                <ul>
                    {messageArr.map((msgObj) => {
                        return (
                            <li key={msgObj.id}>
                                <button onClick={() => this.pushStateShow(msgObj.id, msgObj.title)}>{msgObj.title}(push)</button>
                                <button onClick={() => this.replaceStateShow(msgObj.id, msgObj.title)}>{msgObj.title}(replace)</button>
                            </li>
                        );
                    })}
                </ul>
                <Route path="/message/tip" component={Tip} />
                <button onClick={this.back}>回退</button>&nbsp;
                <button onClick={this.forward}>前进</button>&nbsp;
                <button onClick={this.go}>go</button>
            </div>
        );
    }
}
  1. Detail 组件
js 复制代码
import React, { Component } from "react";

export default class Detail extends Component {
    render() {
        const { id, title } = this.props.match.params;
        return (
            <ul>
                <li>id: {id}</li>
                <li>title: {title}</li>
            </ul>
        );
    }
}
  1. News 组件
js 复制代码
import React, { Component } from "react";
import qs from "qs";

export default class News extends Component {
    render() {
        const { search } = this.props.location;
        const { id, title } = qs.parse(search.slice(1));
        return (
            <ul>
                <li>id: {id}</li>
                <li>title: {title}</li>
            </ul>
        );
    }
}
  1. Tip 组件
js 复制代码
import React, { Component } from "react";

export default class Tip extends Component {
    render() {
        const { id, title } = this.props.location.state || {};
        return (
            <ul>
                <li>id: {id}</li>
                <li>title: {title}</li>
            </ul>
        );
    }
}
2、main
  1. App 组件
js 复制代码
import React, { Component } from "react";
import { Route } from "react-router-dom";
import Message from "./pages/Message";

export default class App extends Component {
    render() {
        return (
            <div>
                <Route path="/message" component={Message} />
            </div>
        );
    }
}
  1. index.js
js 复制代码
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { BrowserRouter } from "react-router-dom";

// 渲染 App 组件到页面
ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById("root"),
);

四、withRouter

1、基本介绍
  1. withRouter 的主要作用是让那些不是通过路由直接渲染的组件,也能访问到路由相关的属性,如 history、location 和 match

  2. 在 React Router 中,只有直接被 Route 渲染的组件,其 props 里会自动获得路由信息

2、演示
  • Header 组件
js 复制代码
import React, { Component } from "react";
import { withRouter } from "react-router-dom";

class Header extends Component {
    back = () => {
        this.props.history.goBack();
    };

    forward = () => {
        this.props.history.goForward();
    };

    go = () => {
        this.props.history.go(-2);
    };

    render() {
        console.log("Header 组件收到的 props 是", this.props);
        return (
            <div className="page-header">
                <h2>React Router Demo</h2>
                <button onClick={this.back}>回退</button>&nbsp;
                <button onClick={this.forward}>前进</button>&nbsp;
                <button onClick={this.go}>go</button>
            </div>
        );
    }
}

export default withRouter(Header);
相关推荐
sbjdhjd16 小时前
Redis 主从复制、哨兵高可用与 Cluster 集群部署实验手册
运维·前端·redis·云原生·开源·bootstrap·html
z落落16 小时前
C# 泛型方法(原理、类型推断、多泛型参数)+泛型效率(普通类型 VS Object装箱 VS 泛型)
开发语言·c#
L_090716 小时前
【C++】异常
开发语言·c++
乐兮创想 小林16 小时前
企业官网移动端性能优化实战:从 Core Web Vitals 到图片/CDN/响应式的工程清单
前端·性能优化·网站建设·北京网站建设公司
疯狂SQL17 小时前
JWT 在线解码、验签、生成一篇讲透:附前端实现、工具架构与在线体验地址
javascript·jwt·编解码·jwt测试
前端一小卒17 小时前
不手写代码的第 30 天,我才明白前端这个岗位还剩什么
前端·javascript·ai编程
Ajie'Blog17 小时前
Copilot Agent Tasks API 开放:AI 编程开始进入后台任务时代
服务器·前端·javascript·人工智能·copilot·ai编程
世辰辰辰17 小时前
批量修改图片/文本名子
开发语言·python·批量修改文件名
老毛肚17 小时前
jeecgboot vue TS & 模板化 04
前端·javascript·vue.js
晓131317 小时前
【Cocos Creator 2.x】篇——第二章 入门
javascript·游戏引擎