抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

阿湫o

一只前端崽

react-router-dom 学习总结

react-router-domreact 的路由模块,本文介绍了 react-router-dom 的基本使用方法。

基本使用步骤:

  1. 安装:yarn add react-router-dom
  2. src/index.js引入:import { Route, BrowserRouter } from 'react-router-dom'
  3. 使用:用包裹需要使用路由的部分(例如:render 函数返回的标签)

BrowserRouter 组件和 Route 组件

BrowserRouterRoute 组件是 react-router-dom 的基本组件

  • BrowserRouter  组件包裹需要使用路由的部分
  • Route  组件用于将路径与组件相关联
// src/index.js
import React, { Component } from 'react'
import Navbar from './components/Navbar'
import Home from './components/Home'
import About from './components/About'
import Contact from './components/Contact'
// 引入react路由
import { Route, BrowserRouter } from 'react-router-dom'

class App extends Component {
    render() {
        return (
            // BrowserRouter 组件包裹需要使用路由的部分,Route 组件用于将路径与组件相关联
            <BrowserRouter>
                                
                <div className='App'>
                                        
                    <Navbar />
                                        
                    {/* exact 开启精准匹配,根路径必须开启此配置,否则只要匹配到带有 / 的路由都会显示出根路径页面 */}
                                        
                    <Route exact path='/' component={Home} />
                                        
                    <Route path='/about' component={About} />
                                        
                    <Route path='/contact' component={Contact} />
                                    
                </div>
                            
            </BrowserRouter>
        )
    }
}

export default App

声明式导航

LinkNavLink 导航组件:

// src/pages/Navbar.js
import React from 'react'
// 引入react-router-dom 路由跳转组件 Link
import { Link, NavLink } from 'react-router-dom'

const Navbar = () => {
    return (
        <nav className='nav-wrapper red darken-3'>
                        
            <div className='container'>
                                
                <Link to='/' className='brand-logo'>
                    React路由
                </Link>
                                
                <ul className='right'>
                                        
                    <li>
                        <Link to='/'>Home</Link>
                    </li>
                                        
                    {/* Link 组件跳转时就只是跳转页面,NavLink 跳转时会在渲染出的 a 标签上加上 active 的 className */}
                                        
                    <li>
                        <NavLink to='/about'>About</NavLink>
                    </li>
                                        
                    <li>
                        <Link to='/contact'>Contact</Link>
                    </li>
                                    
                </ul>
                            
            </div>
                    
        </nav>
    )
}

export default Navbar

编程式导航

<BrowserRouter></BrowserRouter> 包裹的组件的 props 会默认传入 historylocationmatch 这三个对象,history 对象类似 bom(浏览器对象模型)中的 history 对象;

  • history 对象中包含一些用于操作地址栏 urlapi,常用的有:pushreplacego
  • push 用于跳转页面,会在页面栈尾部新增一条记录
  • replace 用于重定向页面,会将当前页面从页面栈中清除,不会留下痕迹
    go 方法接受一个数字作为参数,例如 go(-1) 表示返回上一条路由记录
// src/pages/Contact.js
import React from 'react'

const Contact = (props) => {
    console.log(props)
    setTimeout(() => {
        // push 和 replace 的区别是:
        // push 会在页面栈尾部添加新的页面,可以通过浏览器的返回按钮回到之前的页面
        // replace 会从页面栈中删除当前的页面,再跳转到新的页面
        props.history.push('/') // 跳转
        props.history.replace('/') // 重定向
    }, 2000)
    return (
        <div className='container'>
                        <h3>Contact</h3>
                    
        </div>
    )
}

export default Contact

不被 <BrowserRouter></BrowserRouter> 包裹的组件的 props 中就不会有 history 路由对象,要想让这种组件中拥有路由对象,则可以使用 react-router-dom 中的 withRouter 高阶组件:

//  src/pages/Navbar.js
import React from 'react'
// 引入react-router-dom 路由跳转组件 Link
// 引入 withRouter 高阶组件并将组件作为参数导出后此组件才能使用 history api
import { Link, NavLink, withRouter } from 'react-router-dom'

const Navbar = ({ history }) => {
    console.log(history)
    return (
        <nav className='nav-wrapper red darken-3'>
                        
            <div className='container'>
                                
                <Link to='/' className='brand-logo'>
                    React路由
                </Link>
                                
                <ul className='right'>
                                  
                    <li>
                        <Link to='/'>Home</Link>
                    </li>              
                    {/* Link 组件跳转时就只是跳转页面,NavLink 跳转时会在渲染出的 a 标签上加上 active 的 className */}
                                   
                    <li>
                        <NavLink to='/about'>About</NavLink>
                    </li>
                              
                    <li>
                        <Link to='/contact'>Contact</Link>
                    </li>
                                    
                </ul>
                            
            </div>
                    
        </nav>
    )
}

// 使用 withRouter 高阶组件后此组件将可以使用 history api
export default withRouter(Navbar)

路由传参

声明路由时使用 :xxx 的方式,然后在组件中通过 props.match.params.xxx 来获取

声明路由参数:

// src/index.js
// BrowserRouter 组件包裹需要使用路由的部分,Route 组件用于将路径与组件相关联
<BrowserRouter>
            
    <div className='App'>
                    
        <Navbar />
                    {/* 被 Switch 包裹的路由只会渲染第一个匹配到的路径 */}
                    <Switch>
                            
            {/* exact 开启精准匹配,根路径必须开启此配置,否则只要匹配到带有 / 的路由都会显示出根路径页面 */}
                            
            <Route exact path='/' component={Home} />
                            
            <Route path='/about' component={About} />
                            
            <Route path='/contact' component={Contact} />
            {/* id 表示路由参数 */}
                            
            <Route path='/:id' component={PostDetail} />
                        
        </Switch>
                
    </div>
</BrowserRouter>

获取路由参数:

// src/pages/PostDetail.js
componentDidMount() {
    const { match } = this.props
    // 从 match 对象中获取路由参数
    match.params.id && (this.setState({ id: match.params.id}))
    axios.get('http://jsonplaceholder.typicode.com/posts/' + match.params.id)
        .then(res => {
            res.data && this.setState({ post: res.data })
        })
}



网站内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站总访问量为 访客数为

本站使用 Volantis 作为主题 载入天数...载入时分秒...