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(k8s) v1.24.1 IPv4/IPv6双栈
二进制安装Kubernetes(k8s) v1.24.1 IPv4/IPv6双栈 Kubernetes 开源不易,帮忙点个star,谢谢了 介绍 kubernetes二进制安装 后续尽可能第一时间更新 ...
- 最简单Openwrt ipv6配置,局域网WAN6中继模式获取原生ipv6地址
条件 condition wan 和 wan6 是默认配置 Wan and wan6 are the default configurations 同时wan6可以获取到原生IPv6 ...
- Centos9网卡配置
Centos9 网卡配置文件已修改,如下 [root@bogon ~]# cat /etc/NetworkManager/system-connections/ens18.nmconnection [ ...
- flume基本安装与使用
解压flume包 到/usr/local/src/目录下 [root@hadoopha01 pack]# tar -zxvf apache-flume-1.7.0-bin.tar.gz -C /usr ...
- GDOU-CTF-2023新生赛Pwn题解与反思
第一次参加CTF新生赛总结与反思 因为昨天学校那边要进行天梯模拟赛,所以被拉过去了.16点30分结束,就跑回来宿舍开始写.第一题和第二题一下子getshell,不用30分钟,可能我没想那么多,对比网上 ...
- P1350 车的放置 题解
一.题目描述: 给你一个网格棋盘,a,b,c,d 表示了对应边长度,也就是对应格子数. 例如,当 a=b=c=d=2 时,对应了下面这样一个棋盘: 想要在这个棋盘上放 k 棋子,也就是这 k 个棋子没 ...
- P4055 [JSOI2009] 游戏(博弈论 、最大匹配)
P4055 [JSOI2009] 游戏 目录 P4055 [JSOI2009] 游戏 题目传送门 题目大意 : 思路: code 题目传送门 题目大意 : 小AA和小YY玩游戏,在这个游戏中,同一个格 ...
- 32-webpack详细配置-entry
const HtmlWebpackPlugin = require('html-webpack-plugin') const {resolve} = require('path') /** * ent ...
- 音频处理库性能对比:计算mel频谱的速度哪个更快?
介绍 音频信号处理在各种应用中都发挥着重要的作用,如语音识别.音乐信息检索.语音合成等.其中,Mel频谱是一种常用的频域特征表示方法,用于描述人类听觉系统对频率的敏感程度. 在深度学习音频领域,mel ...
- 关于java中的多态和对实例化对象的一些理解
java面向对象三大特征即为:继承封装多态.而多态需要三大必要条件.分别是:继承.方法重写.父类引用指向子类对象.我们先一个一个来理解. 1.首先是继承和重写.这个很简单.因为多态就是建立在不同的重写 ...