尽管写过 outlet 路由的配置。
考虑到 token 判定和 路由页 变更,我不了解v6是不是有更详解的做法。

决定调一下配置,期望 在任何页面异步更新时,token 都可以在跳转前 被检测到,防止无 token 跳转发生。

为 src 文件配置 v6版本:路由子组件

App.js
import { HashRouter, Routes, Route } from 'react-router-dom';
import Main from './main';
import Login from './page/login'
import Home from './page/home/home'
import About from './page/about/about'
import Integrated from './page/integrated/integrated'
import Sidebar from './page/sidebar/sidebar'
import Latent from './page/latent/latent'
import Particulars from './page/particulars/particulars'
import SecurityCheck from './page/securityCheck/securityCheck'
function App() {
{/* 默认显示页面将不需要填写路径 ,子路由不需要写/斜杠跳转时会带有*/ }
return (
<HashRouter>
<Routes>
{/* Main 负责token的判定(刷新和前往) */}
<Route path='/' element={<Main />} >
<Route path='/login' element={<Login />} ></Route>
<Route path='/about' element={<About />} >
<Route path='' element={<Integrated />} ></Route>
<Route path='sidebar' element={<Sidebar />} >
<Route path='' element={<Latent />} ></Route>
<Route path='particulars' element={<Particulars />} ></Route>
<Route path='securityCheck' element={<SecurityCheck />} ></Route>
</Route>
</Route>
<Route path='/home' element={<Home />} ></Route>
</Route>
</Routes>
</HashRouter>
);
} export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
创建和 App.js 、index.js 同级别的 main.js
// main 组件, 充当 路由子组件的主体
// 判定 page页发生改变
// 判定 token 的 状态变更
// 判定 不存在的页面 404~ import React, { Component, useEffect, useState } from 'react'
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import storage from './util/storage'; const Index = () => {
const location = useLocation(); //获取生命周期钩子(页面变化)
const [pathname, setpathname] = useState() //监听地址变化
const navigate = useNavigate(); //获取生命周期钩子(page跳转)
const Token = storage.get('token'); //获取本地缓存:token
const [newToken, oldToken] = React.useState(Token)
// console.log('Main页打印Token:', Token)
// console.log('Main页打印location.pathname', location.pathname) // let Daa={
// pathname:'', //地址名
// token:'',//附加token
// }
// const [allData,setAllData] =React.useState(Daa) //上下文数据 useEffect(() => { //监听location变化
if (!Token) { //不存在
if (location.pathname === '/') { //地址栏不全
navigate('/login')
}
else if (location.pathname != '/login') {//地址为登录后
navigate('/login')
}
} else { //存在
if (location.pathname === '/') { //地址栏不全
navigate('/login')
}
}
setpathname(location.pathname) //更新page页面名
}, [location])
return <Outlet context={[newToken, oldToken]}></Outlet>
} export class Main extends Component {
render() {
return (
<>
<Index />
</>
)
}
}
export default Main

在src中,创建 util 配置文件夹

配置 storage.js
var storage = {
set(key, value) { // 添加/编辑 缓存
localStorage.setItem(key, JSON.stringify(value)) },
get(key) { // 取出缓存数据
return JSON.parse(localStorage.getItem(key)) }, remover(key) { // 移除指定缓存
localStorage.removeItem(key) }
} export default storage;

为page文件创建

login.js 组件
import React, { Component } from 'react'
import storage from '../../util/storage'
import { useNavigate, useOutletContext } from 'react-router-dom'; const Login = () => {
const [newToken, oldToken] = useOutletContext();
const navigate = useNavigate();
let params = {
message: '这是跳转时携带的参数',
}
const storageToken = () => {
if (!newToken) {
storage.set('token', '这是被存储的token')
navigate('/about', { state: params });
} else {
storage.remover('token')
}
oldToken(() => { return storage.get('token')})
} const Btn = () => {
if (!newToken) {
return <>
<button onClick={storageToken}>点击缓存token</button>
</>
} else {
return <>
<button onClick={storageToken}>点击清除token</button>
</>
}
} return <>
<h4>这里是登录前</h4>
<Btn />
<br />
<span>{newToken}</span>
</>
}
export default Login

about.js 组件
import React from 'react';
import { Outlet, useNavigate, useLocation } from 'react-router-dom'; export default function About() {
const navigate = useNavigate();
// 需要注意的是 useNavigate() 跳转只能在无状态组件中进行
let ddd = ['c', 'n'] const [count, setCount] = React.useState(ddd); // 数据共享
// 需要注意的是,它只能传入两组字段,一组为原始数据,一组变更数据,用作对比时,每次数据变动
// 页面随之更新 传入的数据类型由自己决定 const state = useLocation() //接收参数
console.log('state', state) // navigate('', {}) // 前往默认页
// navigate('/home', {}) // 前往其他页
// navigate('文件名/子文件', {}) //前往子级
// navigate('文件名', {replace: true}) //前往当前路由其他同级页 replace: true 重定向
return (
<>
<h4>About</h4>
<button onClick={() => {
navigate('test', { state: ddd });
// state 传参不限制传参类型
}}>点击Test页</button>
<Outlet context={[count, setCount]} />
</>
)
}

React学习时,outlet配置(token判定,页面path监听)的更多相关文章

  1. 开始学习Django,配置静态登录页面

    开始学习Django,配置静态登录页面 准备阶段 众所周知,Django是一个重量级的设备齐全的web开发框架.在学习Django前我们需要具备如下的知识点: python基础编程 并发 网络编程 H ...

  2. js和jquery实现页面滚动监听

    js和jquery实现页面滚动监听 一.总结 一句话总结:onscroll方法和监听页面元素的高度都可以实现滚动监听. 1.onscroll方法实现滚动监听的核心代码是什么? <body ons ...

  3. jQuery页面滚动监听事件及高级效果插件

    jQuery页面滚动监听事件及高级效果插件 1. One Page scroll (只适用于上下焦点图)http://www.thepetedesign.com/demos/onepage_scrol ...

  4. 配置redis开机自启动和监听

    redis安装好后,每次手动启动很不方便,配置开机自启动. 方法一:设置启动命令到/etc/rc.d/rc.local rc.local文件是系统全局脚本文件,会在其他开机进程脚本文件执行完毕后执行该 ...

  5. android菜鸟学习笔记23----ContentProvider(三)利用内置ContentProvider监听短信及查看联系人

    要使用一个ContentProvider,必须要知道的是它所能匹配的Uri及其数据存储的表的结构. 首先想办法找到访问短信及联系人数据的ContentProvider能接受的Uri: 到github上 ...

  6. ionic2+Angular ionScroll页面滑动监听

    第一:需要在组件中引入相关模块: 第二:如果只是监听页面滑动,只需要标注@ViewChild(Content) content: Content;就可以了. 附加:如果要监听页面的某个元素,并对其进行 ...

  7. JS学习笔记(一)DOM事件和监听

    将事件绑定到元素身上的三种方法: 1.HTML事件处理程序(不推荐使用) 1 <a onclick="hide()"> 2.传统的DOM事件处理程序 即在目标DOM事件 ...

  8. vue页面内监听路由变化

    beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当钩子执行前,组件实 ...

  9. 配置非默认端口的监听Listener

  10. springboot启动配置原理之三(事件监听机制)

    ApplicationContextInitializer public class HelloApplicationContextInitializer implements Application ...

随机推荐

  1. 二进制安装Kubernetes(k8s) v1.25.0 IPv4/IPv6双栈

    二进制安装Kubernetes(k8s) v1.25.0 IPv4/IPv6双栈 Kubernetes 开源不易,帮忙点个star,谢谢了 介绍 kubernetes(k8s)二进制高可用安装部署,支 ...

  2. day115:MoFang:种植园我的背包&种植园道具购买

    目录 1.我的背包 2.道具购买 1.我的背包 1.在种植园点击背包按钮打开我的背包 在种植园打开背包,orchard.html,代码: <!DOCTYPE html> <html& ...

  3. Go For Web:踏入Web大门的第一步——Web 的工作方式

    前言: 本文作为解决如何通过 Golang 来编写 Web 应用这个问题的前瞻,对 Golang 中的 Web 基础部分进行一个简单的介绍.目前 Go 拥有成熟的 Http 处理包,所以我们去编写一个 ...

  4. Linx 阶段一

    Linux Linux常用命令 具体演示 1). ls 2). pwd 3). touch 4). mkdir 5). rm 使用技巧 1. 连按 Tab健自动补齐文件名 2. ll 查看当前目录文件 ...

  5. CTFshow愚人杯-被遗忘的反序列化

    这题虽然只有100的分值,但是我觉得它涉及到的东西还蛮多的,写个随笔记录一下. 题目 <?php # 当前目录中有一个txt文件哦 error_reporting(0); show_source ...

  6. Android事件分发-基础原理和场景分析

    作者:京东零售 郭旭锋 1 为什么需要事件分发 和其他平台类似,Android 中 View 的布局是一个树形结构,各个 ViewGroup 和 View 是按树形结构嵌套布局的,从而会出现用户触摸的 ...

  7. C# 系统菜单弹出框方向

    右键菜单,tootip等弹出时,弹出的位置经常在左侧,使用体验不好. 弹出方向有左对齐和右对齐 SystemParameters.MenuDropAlignment 当右对齐时,值为false 可以在 ...

  8. [Pytorch框架] 1.2、Pytorch环境搭建

    文章目录 1.2 Pytorch环境搭建 1.2.1 安装Pytorch 1.2.2 配置 Jupyter Notebook 1.2.3 测试 1.2.4 问题解决 问题1:启动python提示编码错 ...

  9. 模块 ""element-plus"" 没有导出的成员 "ElMessage"。你是想改用 "import ElMessage from "element-plus"" 吗?

    背景:在使用Element Plus写demo时,导入ElMessage组件出现 [模块 ""element-plus"" 没有导出的成员 "ElMe ...

  10. 这个字段我明明传了呀,为什么收不到 - Spring 中首字母小写,第二个字母大写造成的参数问题

    问题现象 vSwitchId.uShape.iPhone... 这类字段名,有什么特点?很容易看出来吧,首字母小写,第二个字母大写.它们看起来确实是符合 Java 中对字段所推崇的"小驼峰命 ...