React-6 React Router知识

本文详细介绍了React Router的使用,包括其作用、安装步骤、路由导入、定义、重定向、嵌套、跳转、参数传递、拦截、模式、withRouter组件、反向代理以及CSS模块化,帮助开发者深入理解并掌握React路由的各个方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、介绍

1、作用:路由是根据不同的url地址展示不同的页面或者内容

2、安装

二、使用

1、导入

2、定义路由

3、重定向

4、嵌套路由

5、路由跳转

6、路由传参

7、路由拦截

8、路由模式

9、withRouter

10、反向代理

11、css   modul

一、介绍

1、作用:路由是根据不同的url地址展示不同的页面或者内容

2、安装

(1)官网安装:http://reacttraining.com/react-router/web/guides/quick-start

(2)终端安装:

npm install react-router-dom@5

二、使用

1、导入

//引入
import   {HashRouter,  Router}  from  'react-router-dom'

2、定义路由

render(){
     return  (
       <div>
          <HashRouter>
               <Router path="/home"  component={Home}  />
               <Router path="/second"  component={Second}  />
               <Router path="/mine"  component={Mine}  />
          </HashRouter>
       </div>
     )
}

建议:将路由单独封装在一个js文件中

注意:一级路由与多级路由 

3、重定向

作用:如果我们不想让用户访问某个路由或者该路由不在我们书写的路由中,我们可以让组件跳转到我们指定的路由

{/模糊匹配   重定向*/}
{/*<Redirect   from="/"  to="/home"   exact   />*/}
{/*exact   精确地*/}
<Redirect  path="*"   component={Test}  />

4、嵌套路由

(1)父组件

<Route  path="/home"  component={Home}>

(2)子组件Home:直接使用Route

<Route  path="/home/page1"  component={Page1} />
<Route  path="/home/page2"  component={Page2} />
<Redirect  from='/home'  to='home/page1' />

5、路由跳转

(1)声明式路由

<NavLink  to="/home"  activeClassHome="ok">home</NavLink>
<NavLink  to="/second"  activeClassHome="ok">second</NavLink>
<NavLink  to="/mine"  activeClassHome="ok">mine</NavLink>

(2)编程式路由

   <1>this.props.history.push(路由)

   <2> props.history.push(路由)

import  {useHistory}  from  'react-router-dom'

const  history = useHistory()
history.push(路由)

6、路由传参

(1)使用params参数

const index = () => {
 const arr = [
      {id:'001',title:'one'},
      {id:'002',title:'two'},
      {id:'003',title:'three'},
    ]
  return (
    <div>
      <ul>
        {
          arr.map((msg) => (
            <li key={msg.id}>
              {/* 向路由组件传递params参数 */}
              <Link to={`/home/message/detail/${msg.id}/${msg.title}`}>{msg.title}</Link>
            </li>
          ))
        }
      </ul>
      <hr />
      {/* 声明接收params参数 */}
      <Route path='/home/message/detail/:id/:title' component={Detail} />
    </div>
  )
}
 
 
const index = (props) => {
    const data = [
        {id:'001',text:'第一名'},
        {id:'002',text:'第二名'},
        {id:'003',text:'第三名'},
    ]
    //接收params参数
    const {id, title} = props.match.params
    const SearchResult = data.find((dataobj) => {
        return dataobj.id === id;
    })
  return (
    <div>
        <ul>
            <li>id:{id}</li>
            <li>title:{title}</li>
            <li>nm:{SearchResult.text}</li>
        </ul>
 
    </div>
  )
}

   <1>传递params参数

<Link  to='/demo/test/001/aa'>展示</Link>

   <2>声明接收params参数

<Route  path='/demo/test/:id/:title'   component='{Test}' />

   <3>接收params参数

const   {id, title} = props.match.params

(2)使用search参数

const index = () => {
 const arr = [
      {id:'001',title:'one'},
      {id:'002',title:'two'},
      {id:'003',title:'three'},
    ]
  return (
    <div>
      <ul>
        {
          arr.map((msg) => (
            <li key={msg.id}>
              {/* 向路由组件传递search参数 */}
              <Link to={`/home/message/detail/?id=${msg.id}&title=${msg.title}`}> {msg.title}</Link>
            </li>
          ))
        }
      </ul>
      <hr />
      <Route path='/home/message/detail' component={Detail} />
    </div>
  )
}
 
 
const index = (props) => {
    const detaildata = [
        {id:'001',text:'第一名'},
        {id:'002',text:'第二名'},
        {id:'003',text:'第三名'},
    ]
    //接收search参数
    const {search} = props.location
    const querystring = require('querystringify')
    const obj = querystring.parse(search.slice(1)) 
    const {id, title} = obj   
 
    const SearchResult = detaildata.find((dataobj) => {
        return dataobj.id === id;
    })
  return (
    <div>
      <ul>
        <li>id:{id}</li>
        <li>title:{title}</li>
        <li>nm:{SearchResult.text}</li>
      </ul>
    </div>
  )
}

   <1>传递参数

<Link  to='/demo/test?id=001&title=aa'>展示</Link>

   <2>不用声明接收

<Route  path='/demo/test'  component='{Test}' />

   <3>接收search参数:接收到的数据为字符串形式,需要转换成对象

(3)使用state参数

   <1>传递state参数

<Link  to={{pathname:'/home/message/detail', state:{id:'001',title:'aa'}}}>展示</Link>

   <2>不用声明接收

<Route  path='/demo/test/'  component='{Test}' />

   <3>接收state参数

const  {id, title} = props.location.state

注意: 刷新后对路由state参数的影响

<1>BrowserRouter没有任何影响,因为state保存在history对象中。

<2>HashRouter刷新后会导致路由state参数的丢失

7、路由拦截

(1)使用Prompt组件来完成

   <1>参数when:boolean型

         作用:true弹窗,false顺利跳转。

   <2>参数message:function或者字符串

         作用:函数返回true就顺利跳转,false停止跳转字符串就弹窗字符串并停止跳转。

注意:当when值为true并且message是函数返回值为false时,才会拦截路由并且不会弹出默认弹出框。

import {  Dialog } from '@alifd/meet-react';
import React, { useEffect, useState} from 'react';
import { Prompt, useHistory } from 'react-router';

import style from './index.module.scss';

export default function TestPage() {
  const history = useHistory();
  const [notAllowJump, setNotAllowJump] = useState(true);

  /**
   * 路由拦截
   * @param {*} location string
   * @returns boolean
   */
  function handleRouter() {
    const list = field.getValue('list');
    const equal = xxxxx(); // 判断两次值是不是一样 
    if (equal) {
    // 两次值一样,用户没改动数据,直接放行
      return true;
    }
    Dialog.show({
      centered: true,
      content: '是否保存当前修改数据',
      onOk() {
      	// 用户需要提交,提交后要放行,先将when置为false,再提交操作
        setNotAllowJump(false);
        xxxxxSubmit(); // 继续提交
      },
      async onCancel() {
      	// 用户不提交,直接放弃修改返回上一页。将when置为false再返回,注意setNotAllowJump操作是异步的。
        await setNotAllowJump(false);
        history.goBack();
      },
    });
    // 用户有修改,返回false拦截跳转,同时屏蔽掉默认弹出框
    return false;
  }

  return (
    <div className={style['test-page']}>
      <Prompt when={notAllowJump} message={handleRouter} />
      <footer>
        我是页面内容
      </footer>
    </div>
  );
}

(2)使用history.block拦截

   <1>当返回值为true,路由会跳转,不会弹出默认框。

   <2>当返回值为false,路由不会跳转,不会弹出默认框。

   <3>当返回值为string,路由不会跳转,会弹出默认框。

注意:当block返回值是false时候,能够拦截路由跳转,并且不会弹出默认提示框。

import { useHistory } from 'react-router';
import {  Dialog } from '@alifd/meet-react';
import React, { useEffect, useState} from 'react';

import style from './index.module.scss';

export default function TestPage() {
  const history = useHistory();
  
  useEffect(() => {
    history.block(() => {
      Dialog.show({
        centered: true,
        content: '是否保存当前修改数据',
        onOk() {
          history.block(() => true); // 放开拦截提交操作,成功后在提交函数内跳出去
          xxxxxSubmit();
        },
        async onCancel() {
          history.block(() => true);
          history.goBack();
        },
      });
      // 开启路由拦截同时阻止默认弹出框
      return false;
    });
  }, [history]);

  return (
    <div className={style['test-page']}>
      <footer>
        我是页面内容
      </footer>
    </div>
  );
}

8、路由模式

(1)HashRouter(哈希路由)

   <1>根据URL地址中的哈希值来确定显示的组件http://localhost:3000/#/first)

   <2>hash的变化,不会导致页面刷新,兼容性较好。

(2)BrowserRouter(浏览器路由)

   <1>使用 H5 的 history.pushState API 实现 (http://localhost:3000/first)

   <2>推荐使用浏览器路由。

9、withRouter

(1)作用:可以让一般组件(没有通过component渲染的组件)获取到history属性

(2)使用方法

   <1>在需要使用history属性的组件中引入withRouter(原理:高阶组件)

import {withRouter} from 'react-router-dom'

   <2>默认导出

export default withRouter(组件名称)

10、反向代理

(1)解决跨域问题

(2)参考链接:Proxying API Requests in Development | Create React App

(3)开始使用

   <1>安装插件:nmp install http-proxy-middleware   --save

const {createProxyMiddleware} = require('http-proxy-middleware')
    module.exports = function (app) {
        app.use(
             '/api',
             createProxyMiddleware({
                 target:'目标URL',
                 changeOrigin: true
            }
        )
    )
        }

   <2>在src文件夹下创建setupProxy.js文件

   <3>重新启动app

11、css   module

(1)spa应用,在任意js引入css代码都有相当于在head标签内引入,如果是多组件或者多人开发如何避免冲突

(2)我们建议每一个组件都可以放入一个同名文件夹中,这样js与css在一起

(3)css命名时写成 eg.   A.module.css

   <1>这样这个css样式只对A起作用

   <2>注意 :不要单独写  标签名选择器

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值