首页 > 其他分享 >React学习时,outlet配置(token判定,页面path监听)

React学习时,outlet配置(token判定,页面path监听)

时间:2023-06-28 14:48:11浏览次数:29  
标签:const navigate storage React token outlet import page

尽管写过 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]} />
        </>
    )
}

标签:const,navigate,storage,React,token,outlet,import,page
From: https://www.cnblogs.com/JoJo-home/p/17509784.html

相关文章

  • React - 判断当前点击是组件的外部或内部
    1.先获取当前要监听的那个组件的refimportReact,{useRef}from'react';//类组件获取this.Ref=React.createRef();//函数组件获取constRef=useRef();2.通过addEventListener来全局监听document.addEventListener("mousedown",(e)=>{if(Ref.contains(e.ta......
  • React ISR 如何实现 - 最后的 Demo
    之前写了两个demo讲解了如何实现SSR和SSG,今天再写个demo说在ISR如何实现。什么是ISRISR即IncrementalStaticRegeneration增量静态再生,是指在SSG的前提下,可以在收到请求时判定页面是否需要刷新,如果需要则重新构建该页面,这样既拥有了静态页面的优势又可以避免页......
  • 无感刷新token
    无感刷新token//首先需要在响应拦截里面加一个code反馈码的判断是401就调用刷新token的方法//响应拦截api.interceptors.response.use((response:any)=>{if(response.data.code==200){done();returnresponse;}elseif(response.dat......
  • React基础
    一、ReactHook(部分)1.useEffectuseEffect用于处理组件中的effect,通常用于请求数据,事件处理,订阅等相关操作。1.当useEffect没有第二个参数时,useEffect会不停的调用2.当useEffect第二个参数为空数组时,仅在组件挂载和卸载时调用3.当useEffect第二个参数为变量时,例如[co......
  • TypeError: token.type.endsWith is not a function
    起因公司产品项目拉下来,安装完依赖就报这个错误token.type.endsWithisnotafunction 解决方案发现是eslint的版本将 babel-eslint版本为10.1.0,把版本降为8.2.2,即重新安装指定版本的依赖。重新安装,并重启后,解决问题 [email protected] ......
  • react的函数式组件中使用ref获取到子组件的方法为undefined
    我暂时遇到了两种情况。第一种情况:useImperativeHandle函数写错useImperativeHandle的第二个参数的返回值是作为ref.current的值,但是我写箭头函数写快了,忘记返回值了。useImperativeHandle(ref,()=>{foo},[foo])//错误,这样没有返回值,所以ref.current为undefineduseImp......
  • HTML Over the wire 框架 Unpoly 和 React 的使用场合比较
    Unpoly是一个轻量级的JavaScript框架,它允许您通过HTMLoverthewire的方式进行Web应用程序开发。HTMLoverthewire是一种网络通信模式,它将由服务器生成的HTML片段作为响应发送给客户端,而不是传统的JSON数据。这样,服务器端可以处理更多逻辑,而客户端可以专注于渲染和......
  • 6月26日java&React学习日记
    今日学习java的异常处理,了解了多try,catch,以及单try多catch(需注意子类在上父类在下)异常捕获的方法。同时也学习了React框架,该框架确实比较好用但上手难度较高,需理解其组件化原理,改框架涉及ES6比较深,需加强js或ts的学习。 ......
  • 【Node】node 报错:tagOffsetsMap[tag] ??= [];...SyntaxError: Unexpected token ,‘??=
    安装的node版本不支持空值赋值运算符(??=)更换合适的node版本就行更多支持请在node.green上查看各种语法支持的版本参考文章NodeJS中的空合并赋值运算符(??=)......
  • 【HMS Core】web端网页应用集成账号服务,请求/oauth2/v3/token返回状态码403
    【问题描述】web端网页应用接入华为账号,请求/oauth2/v3/token返回状态码403请求代码:响应日志:【问题分析】这是由于跨域访问报错了,建议从服务器端调用token接口重试,不要把client_secret暴露到web端【解决方案】服务器端调用token接口参考链接:https://developer.huawei.com/consumer......