您现在的位置是:首页 >技术交流 >React脚手架搭建项目知识点----路由(二)网站首页技术交流

React脚手架搭建项目知识点----路由(二)

Daisy__1 2023-06-15 00:00:03
简介React脚手架搭建项目知识点----路由(二)

一、路由的基本使用

  1. 明确好界面中的导航区、展示区
  2. 导航区的a标签改为Link标签
<Link to="/xxxxx">Demo</Link>
  1. 展示区写Route标签进行路径的匹配
{/* v5版本: */}
<Route path='/xxxx' component={Demo}/>

{/* v6版本: */}
<Route path='/xxxx' element={<Demo/>}/>
  1. 的最外侧包裹了一个或,用来管理路由
ReactDOM.render(
   <BrowserRouter>
     <App />
   </BrowserRouter>,
   document.getElementById('root')
)

二、NavLink与封装NavLink

  1. NavLink可以实现路由链接的高亮,通过activeClassName指定样式名
  2. 标签体内容是一个特殊的标签属性
  3. 通过this.props.children可以获取标签体内容

三、路由传参

1. params传参
    v5:
        路由链接(携带参数):
            <Link to={`/home/message/detail/${msg.id}/${msg.title}`}>{msgObj.title}</Link>
        注册路由(声明接收) :
            <Route path='/home/message/detail/:id/:title' component={Detail} /> 
        接收参数 :
            const { id,title } = this.props.match.params

    v6:(使用函数组件,并且通过引入 useParams 来实现参数的接收)
        路由链接(携带参数):
            <Link to={`detail/${msg.id}/${msg.title}`}>{msg.title}</Link>
        注册路由(声明接收):
            <Routes> 
                <Route path='detail/:id/:title' element={<Detail/>} /> 
            </Routes>
        接收参数 :
            import { useParams } from 'react-router-dom';
            const params = useParams(); 
            const {id,title} = params;

2. search传参
    v5:
        路由链接(携带参数):
            <Link to={`/home/message/detail?id=${msg.id}&title=${msg.title}`}>{msgObj.title}</Link>
        无需注册路由(正常注册) :
            <Route path='/home/message/detail' component={Detail} /> 
        接收参数 :
            import {qs} from 'querystring'
            const {search} = this.props.location;
            const {id,title} = qs.parse(search.slice(1)); //截取

    v6:(使用函数组件,并且通过引入 useSearchParams 来实现参数的接收)
        路由链接(携带参数):
            <Link to={`detail?id=${msg.id}&title=${msg.title}`}>{msg.title}</Link>
        无需注册路由(正常注册):
            <Routes> 
                <Route path='detail' element={<Detail/>} /> 
            </Routes>
        接收参数 :
            import { useSearchParams } from 'react-router-dom';
            const [params] = useSearchParams(); 
            const id = params.get('id');
            const title = params.get('title');

3. state参数(刷新界面也可以保留参数)
    v5:
        路由链接(携带参数):
            <Link to={{pathname:'home/message/detail',state:{id:msg.id,title:msg.title}}}>{msg.title}<Link/>
        无需注册路由(正常注册) :
            <Route path='/home/message/detail' component={Detail} /> 
        接收参数 :
            const {id,title} = this.props.location.state

    v6:(使用函数组件,并且通过引入 useLocation 来实现参数的接收)
        路由链接(携带参数):
            <Link to='detail' state={{id: msg.id, title: msg.title}}>{msg.title}</Link>
        无需注册路由(正常注册):
            <Routes> 
                <Route path='detail' element={<Detail/>} /> 
            </Routes>
        接收参数 :
            import { useLocation } from 'react-router-dom';
            const location = useLocation(); 
            const {id,title} = location.state;

四、编程式路由导航

1. v5
    // push跳转+携带params参数
    this.props.history.push(`/home/message/detail/${id}/${title}`);
    // push跳转+携带search参数
    this.props.history.push(`/home/message/detail?id=${id}&title=${title}`);
    // push跳转+携带state参数
    this.props.history.push(`/home/message/detail`, { id, title });

    // replace跳转+携带params参数
    this.props.history.replace(`/home/message/detail/${id}/${title}`)
    // replace跳转+携带search参数
    this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)
    // replace跳转+携带state参数
    this.props.history.replace(`/home/message/detail`, { id, title });

    // 前进
    this.props.history.goForward();
    // 回退
    this.props.history.back();
    // 前进或回退 ( go )
    this.props.history.go(-2); //回退到前2条的路由

    // 在一般组件中使用编程式路由导航 (非路由组件)
    import {withRouter} from 'react-router-dom'
    class Header extends Component {
        // withRouter(Header)后,就可以在一般组件内部使用 this.props.history 
        //...
    }
    export default withRouter(Header) // 将一般组件包裹后返回,使一般组件的props中也携带路由相关的三个参数


2. v6
    // v6版本编程导航使用 useNavigate (以下为引入代码)
    import {  useNavigate } from "react-router-dom";
    export default function A() {
        const navigate = useNavigate();
        //...
    }

    // push跳转+携带params参数
    navigate(`detail/${id}/${title}`);
    // push跳转+携带search参数
    navigate(`detail?id=${id}&title=${title}`);
    // push跳转+携带state参数
    navigate(`detail`, {state: { id, title }});

    // replace跳转+携带params参数
    navigate(`detail/${id}/${title}`, {replace: true})
    // replace跳转+携带search参数
    navigate(`detail?id=${id}&title=${title}`, {replace: true})
    // replace跳转+携带state参数
    navigate(`detail`, {state: { id, title }, replace: true});
    
    // 前进
    navigate(1);
    // 回退
    navigate(-1);
    // 前进或回退 ( go )
    navigate.go(-2); //回退到前2条的路由

    withRouter v6已被移除,v6中一般组件也可以使用useNavigate跳转,不需要withRouter

五、BrowserRouter与HashRouter的区别

1. 底层原理不一样:
    BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
    HashRouter使用的是URL的哈希值。
2. path表现形式不一样
    BrowserRouter的路径中没有#,例如: localhost:3000/demo/test
    HashRouter的路径包含#,例如: localhost:3000/#/demo/test
3. 刷新后对路由state参数的影响
    (1) BrowserRouter没有任何影响,因为state保存在history对象中
    (2) HashRouter刷新后会导致路由state参数的丢失!!!
4. 备注: HashRouter可以用于解决一些路径错误相关的问题。
附:解决多级路径刷新页面样式丢失的问题
  1. public/index.html 中 引入样式时不写./ 写 /(常用)
  2. public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)
  3. 使用HashRouter包裹 App组件
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。