React学习时,outlet配置(token判定,页面path监听)
尽管写过 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监听)的更多相关文章
- 开始学习Django,配置静态登录页面
开始学习Django,配置静态登录页面 准备阶段 众所周知,Django是一个重量级的设备齐全的web开发框架.在学习Django前我们需要具备如下的知识点: python基础编程 并发 网络编程 H ...
- js和jquery实现页面滚动监听
js和jquery实现页面滚动监听 一.总结 一句话总结:onscroll方法和监听页面元素的高度都可以实现滚动监听. 1.onscroll方法实现滚动监听的核心代码是什么? <body ons ...
- jQuery页面滚动监听事件及高级效果插件
jQuery页面滚动监听事件及高级效果插件 1. One Page scroll (只适用于上下焦点图)http://www.thepetedesign.com/demos/onepage_scrol ...
- 配置redis开机自启动和监听
redis安装好后,每次手动启动很不方便,配置开机自启动. 方法一:设置启动命令到/etc/rc.d/rc.local rc.local文件是系统全局脚本文件,会在其他开机进程脚本文件执行完毕后执行该 ...
- android菜鸟学习笔记23----ContentProvider(三)利用内置ContentProvider监听短信及查看联系人
要使用一个ContentProvider,必须要知道的是它所能匹配的Uri及其数据存储的表的结构. 首先想办法找到访问短信及联系人数据的ContentProvider能接受的Uri: 到github上 ...
- ionic2+Angular ionScroll页面滑动监听
第一:需要在组件中引入相关模块: 第二:如果只是监听页面滑动,只需要标注@ViewChild(Content) content: Content;就可以了. 附加:如果要监听页面的某个元素,并对其进行 ...
- JS学习笔记(一)DOM事件和监听
将事件绑定到元素身上的三种方法: 1.HTML事件处理程序(不推荐使用) 1 <a onclick="hide()"> 2.传统的DOM事件处理程序 即在目标DOM事件 ...
- vue页面内监听路由变化
beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当钩子执行前,组件实 ...
- 配置非默认端口的监听Listener
- springboot启动配置原理之三(事件监听机制)
ApplicationContextInitializer public class HelloApplicationContextInitializer implements Application ...
随机推荐
- kubernetes 设置 Master 可调度与不可调度
kubernetes 设置 Master 可调度与不可调度 语法 kubectl taint node [node] key=value[effect] [effect] 可取值: [ NoSched ...
- [数据库/MYSQL]MYSQL开启Bin-Log
1 概述: MYSQL数据库的二进制日志----bin log 什么是二进制日志(binlog)? MySQL的二进制日志binlog,可以说是MySQL最重要的日志,它记录了所有的DDL和DML语句 ...
- 授权普通用户 sudo -i 使其具有root的权限
1.ssh 秘钥登录授权 将此代码片更名为 adduser.sh 放在linux的 /root 目录下 #!/bin/sh echo 'ssh-key:' $1 echo 'username:' $ ...
- 如何训练个人的ChatGpt4
如何在自己的计算机上安装类似 ChatGPT 的个人 AI 并在没有互联网的情况下运行它 本文旨在为任何人安装此软件.最初它有一个视频,伴随着操作方法,但是事情变化很快,我的三次尝试只是推迟了我发表这 ...
- Sentinel为什么这么强,我扒了扒背后的实现原理
大家好,我是三友~~ 最近我在整理代码仓库的时候突然发现了被尘封了接近两年之久的Sentinel源码库 两年前我出于好奇心扒了一下Sentinel的源码,但是由于Sentinel本身源码并不复杂,在简 ...
- 大话AI绘画技术原理与算法优化
引子 博主很长一段时间都没有发文,确实是在忙一些技术研究. 如标题所示,本篇博文主要把近段时间的研究工作做一个review. 看过各种相关技术的公关文章,林林总总,水分很多. 也确实没有多少人能把一些 ...
- Prism Sample 16-RegionContext
终于发现一个有趣的新知识了. 本例的核心是RegionContext,意思是一个区域的上下文.但与DataContext似乎并不相同. 先看一下整体思路. 在主窗体上只有一个Region: <G ...
- 我做了一个 VSCode 插件版的 ChatGPT
大家好,我是风筝 其实很早之前就想学学 VSCode 插件开发了,但是又不知道做什么,加上我这半吊子前端水平,迟迟没有动手. 最近 ChatGPT 火的一塌糊涂,我也一直在用,真的非常好用,有些问题之 ...
- 2020-08-22:I/O多路复用中select/poll/epoll的区别?
福哥答案2020-08-22: select,poll,epoll 都是 操作系统实现 IO 多路复用的机制. 我们知道,I/O 多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是 ...
- 2021-10-29:除自身以外数组的乘积。给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之
2021-10-29:除自身以外数组的乘积.给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i ...