欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

使用 React 进行路由导航与参数传递

最编程 2024-08-08 09:27:11
...

路由跳转

路由跳转的方式是分为标签跳转和编程式跳转。

import {Link, useNavigate} from 'react-router-dom';

Line标签跳转
<Link to='/des'>标签跳转到详情页</Link>
<Link to={{pathname:'/center'}}>标签跳转到个人中心</Link>

useNavigate编程式跳转
let navgite=useNavigate();
  let todes=()=>{
    navgite('/des');
  };
  let tocenter=()=>{
    navgite({pathname:'/center'});
  }
<button onClick={todes}>编程式跳转到详情页</button>
<button onClick={tocenter}>编程式跳转到个人中心</button>

Link相当于超连接,它和a标签的区别是,Link不会刷新整个网站,只是切换路由页面渲染不同组件。而a标签会再次重新请求整个网站然后刷新网页,a标签多用于和外部网站建立链接。

React中懒加载组件导致的路由跳转错误(踩坑)

lazy函数用于懒加载,即当用到的时候才会开始加载,但是路由跳转是立刻完成的,所以在React最新开发环境中会直接报错。解决方案是使用React提供的新组件Suspense解决,这个还能实现时加载显示加载动画的功能。

import React, { lazy } from 'react'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import First from '../views/first/index.jsx'
import Des from '../views/des/index.jsx'
const Des = lazy(() => import('../views/des/index.jsx'))
const Usercenter = lazy(() => import('../views/usercenter/index.jsx'))
export default function Index() {
    return (
            <Router>
                <Routes>
                    <Route path='/first' element={<First></First>}></Route>
                    <Route path='/des' element={<Des />}></Route>
                    <Route path='/center' element={<Usercenter />}></Route>
                    <Route path='/*' element={<First />}></Route>
                </Routes>
            </Router>
    )
}
import React from 'react'
import {Link,useNavigate} from 'react-router-dom'
export default function Index() {
  let navgite=useNavigate();
  let todes=()=>{
    navgite('/des');
  };
  let tocenter=()=>{
    navgite({pathname:'/center'});
  }
  return (
    <div>
      <h1>Index 首页</h1>
      <h2>标签跳转</h2>
      <Link to='/des'>标签跳转到详情页</Link>
      <br />
      <Link to={{pathname:'/center'}}>标签跳转到个人中心</Link>
      <h2>编程式跳转</h2>
      <button onClick={todes}>编程式跳转到详情页</button>
      <br />
      <button onClick={tocenter}>编程式跳转到个人中心</button>
    </div>
  )
}

2.gif

image.png

解决方法:

import React, { lazy,Suspense } from 'react'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import First from '../views/first/index.jsx'
const Des = lazy(() => import('../views/des/index.jsx'))
const Usercenter = lazy(() => import('../views/usercenter/index.jsx'))
export default function Index() {
    return (
            <Router>
                <Routes>
                    <Route path='/first' element={<First></First>}></Route>
                    <Route path='/des' element={<Suspense><Des /></Suspense>}></Route>
                    <Route path='/center' element={<Suspense><Usercenter /></Suspense>}></Route>
                    <Route path='/*' element={<First />}></Route>
                </Routes>
            </Router>
    )
}

路由传参

search传参(通过url传参数)

search传参是将参数拼接在网址的querystring中。

优点:刷新页面后参数不丢失

缺点:只能传字符串,传值过多url会变得很长,获取参数需要自己解析字符串。

传参的使用

import React from 'react'
import {Link,useNavigate} from 'react-router-dom'
export default function Index() {
  let navgite=useNavigate();
  let todes=()=>{
    navgite({pathname:'/des',search:'gid=89'});
  return (
    <div>
      <h1>Index 首页</h1>
      <h2>标签跳转</h2>
      <Link to='/des?gid=67'>标签跳转到详情页</Link>
      <h2>编程式跳转</h2>
      <button onClick={todes}>编程式跳转到详情页</button>
    </div>
  )
}

ps:当使用对象用pathname跳转传参时不能在pathname后面直接拼接参数会报错,必须使用search属性且属性值只能是字符串,当传参需要变量动态取值只能使用反引号的模板字符串,不能是对象。

navgite({pathname:'/des?gid=89'}); 错误写法
navgite({pathname:'/des',search:'gid=89'}); 正确写法
navgite('/des?gid=89'); 正确写法
let gid=89;
navgite(`/des?gid=${gid}`); 正确写法

接受参数的使用useLocation

import React from 'react'
import {useLocation} from 'react-router-dom'
export default function Index() {
  let searchcanshu=useLocation();
  console.log(searchcanshu,666);
  // 接受search参数
  console.log(searchcanshu.search,777);
  return (
    <div>Des 详情页</div>
  )
}

image.png

解析参数的方法

export default function(str){
    if(str.indexOf('?')!=-1){
        let obj={};
        str.split("?")[1].split("&").map((el)=>{
            let arr=el.split('=');
            obj[arr[0]]=arr[1];
        });
        return obj;
    }else{
        return;
    }
}
import React from 'react'
import {useLocation} from 'react-router-dom'
import inAnaly from '../../inAnaly.js';
export default function Index() {
  let searchcanshu=useLocation();
  console.log(searchcanshu,666);
  // 接受search参数
  console.log(searchcanshu.search,777);
  console.log(inAnaly(searchcanshu.search),888);
  return (
    <div>Des 详情页</div>
  )
}

image.png

image.png

动态传参数(params传参)

params传参是将参数拼接在网址的pathname中。

优点:刷新页面,参数不丢失

缺点:1.只能传字符串,传值过多url会变得很长 2. 参数必须在路由上配置

第一步设置可传参数,第二步传参数,第三步使useParams接收参数

1.设置可传参数
<Route path='/center/:name/:uid' element={<Suspense><Usercenter /></Suspense>}></Route>
2.传参
navigate({pathname:`/center/utc_20090729/6`});
或
<Link to={{pathname:`/center/utc_19890530/7`}}>跳转到个人中心</Link>
3.接收参数
import {useParams} from 'react-router-dom';
let person = useParams();
console.log(person.name,person.uid)
import React from 'react'
import {Link,useNavigate} from 'react-router-dom'
export default function Index() {
  let navgite=useNavigate();
  let todes=()=>{
    navgite({pathname:'/des',search:'gid=89'});
  };
  let tocenter=()=>{
    navgite({pathname:`/center/utc_20090729/6`});
  }
  return (
    <div>
      <h1>Index 首页</h1>
      <h2>search传参</h2>
      <Link to='/center'>标签跳转到个人中心</Link>
      <br />
      <button onClick={todes}>编程式跳转到详情页</button>
      <hr />
      <h2>param传参</h2>
      <Link to={{pathname:`/center/utc_19890530/7`}}>标签跳转到详情页</Link>
      <br />
      <button onClick={tocenter}>编程式跳转到个人中心</button>
    </div>
  )
}

import React from 'react'
import { useParams } from 'react-router-dom'
export default function Index() {
    // 接受参数
    let person = useParams();
    console.log(person,666666);
    console.log(person.name, person.uid,777777);
    return (
        <div>
            <h1>个人中心</h1>
        </div>
    )
}

image.png

state传参

优点:可以传对象,参数不会拼接在网址中,可以用于传不用给用户看见的参数

缺点: <HashRouter>刷新页面,参数丢失

官方建议使用<BrowserRouter><BrowserRouter>页面刷新参数也不会丢失。

//传递参数关键代码
import {useNavigate} from 'react-router-dom';
let navigate = useNavigate();
navgite({pathname:'/center'},{state:{token:'utc_19890418',uid:7}});
<Link to={{pathname:`/center`}} state={{token,uid}}>标签跳转到个人中心</Link>

import React from 'react'
import {Link,useNavigate} from 'react-router-dom'
export default function Index() {
  let navgite=useNavigate();
  let tocenter=()=>{
    navgite({pathname:'/center'},{state:{token:'utc_19890418',uid:7}});
  };
  let token='utc_20090729';
  let uid=6;
  return (
    <div>
      <h1>Index 首页</h1>
      <h2>state传参</h2>
      <Link to={{pathname:`/center`}} state={{token,uid}}>标签跳转到个人中心</Link>
      <br />
      <button onClick={tocenter}>编程式跳转到个人中心</button>
    </div>
  )
}

接收参数使用hook-useLocation函数,接收到的对象state是一个Object类型

import React from 'react'
import { useLocation } from 'react-router-dom'
export default function Index() {
    // 接受参数
    let person = useLocation();
    console.log(person,666666);
    console.log(person.state,777777);
    return (
        <div>
            <h1>个人中心</h1>
        </div>
    )
}

image.png

跳转时可以将search和state同时传入

import React from 'react'
import {Link,useNavigate} from 'react-router-dom'
export default function Index() {
  let navgite=useNavigate();
  let tocenter=()=>{
    navgite({pathname:'/center',search:'19960311'},{state:{token:'utc_19890418',uid:7}});
  };
  let token='utc_20090729';
  let uid=6;
  return (
    <div>
      <h1>Index 首页</h1>
      <h2>state传参</h2>
      <Link to={{pathname:`/center`,search:'19910816'}} state={{token,uid}}>标签跳转到个人中心</Link>
      <br />
      <button onClick={tocenter}>编程式跳转到个人中心</button>
    </div>
  )
}


import React from 'react'
import { useLocation } from 'react-router-dom'
export default function Index() {
    // 接受参数
    let person = useLocation();
    console.log(person,666666);
    console.log(person.state,777777);
    return (
        <div>
            <h1>个人中心</h1>
        </div>
    )
}

image.png

推荐阅读