React 路由

React 的路由跳转需要引用第三方的 React Router

npm i react-router-dom@5.2.0

React Router 分为 BrowserRouter 和 HashRouter

如果我们的应用有服务器响应 web 的请求,建议使用<BrowserRouter>组件; 如果使用静态文件服务器,建议使用<HashRouter>组件

 在 React router 中通常使用的组件有三种(这里使用的是Router5):

  • 路由组件(作为根组件): BrowserRouter(history模式) 和 HashRouter(hash模式)
  • 路径匹配组件: Route 和 Switch
  • 导航组件: Link 和 NavLink

BrowserRouter 和 HashRouter 的使用

  • BrowserRouter 和 HashRouter 包裹的路由组件会自动传入match、history、location。
  • BrowserRouter 的路径:localhost:3000/demo/a
  • HashRouter 的路径:localhost:3000/#/demo/a
  • BrowserRouter 刷新没有任何影响,因为 state 保存在 history 对象中。
  • HashRouter 刷新后会导致路由state参数的丢失!!!
  • BrowserRouter 可以传递任意参数,HashRouter 需要手动拼接 URL
//BrowserRouter
class App extends Component {
  render() {
    return (
      <BrowserRouter>
          <Header />
          <Route path='/' exact component={Home}></Route>
          <Route path='/login' exact component={Login}></Route>
          <Route path='/detail/:id' exact component={Detail}></Route>
      </BrowserRouter>
    )
  }
}

//HashRouter
class App extends Component {
  render() {
    return (
      <HashRouter>
          <Header />
          <Route path='/' exact component={Home}></Route>
          <Route path='/login' exact component={Login}></Route>
          <Route path='/detail/:id' exact component={Detail}></Route>
      </HashRouter>
    )
  }
}

Route: 用来控制路径对应显示的组件

  • path:指定路由跳转路径
  • exact:精确匹配路由
  • component:路由对应的组件
  • render:通过写render函数返回具体的dom
  • location: 将 与当前历史记录位置以外的位置相匹配,则此功能在路由过渡动效中非常有用
  • sensitive:是否区分路由大小写
  • strict: 是否配置路由后面的 '/'
<Route path='/about' exact render={() => <About /> }></Route>

Switch:只是匹配到第一个路由后,就不再继续匹配

<Switch> 
    <Route path='/home'  component={Home}></Route>
    <Route path='/login'  component={Login}></Route> 
    <Route path='/detail' exact  component={detail}></Route> 
    <Route path='/detail/:id'  component={detailId}></Route> 
    <Redirect to="/home" from='/' /> //重定向
</Switch>

【注意】:如果路由 Route 外部包裹 Switch 时,路由匹配到对应的组件后,就不会继续渲染其他组件了。但是如果外部不包裹 Switch 时,所有路由组件会先渲染一遍,然后选择到匹配的路由进行显示。

Link 和 NavLink:它们都可以用来指定路由跳转,NavLink 的可选参数更多。

  • pathname: 表示要链接到的路径的字符串。
  • search: 表示查询参数的字符串形式。
  • hash: 放入网址的 hash,例如 #a-hash。
  • state: 状态持续到 location。通常用于隐式传参(埋点),可以用来统计页面来源
通过字符串执行跳转路由:
<Link to='/login'>
    <span>登录</span>
</Link>

通过对象指定跳转路由:
<Link to={{
        pathname: '/login',
        search: '?name=cedric',
        hash: '#someHash',
        state: { fromWechat: true }
    }}>
    <span>登录</span>
</Link>

NavLink跳转:

可以看做 一个特殊版本的 Link,当它与当前 URL 匹配时,为其渲染元素添加样式属性。

  • exact: 如果为 true,则仅在位置完全匹配时才应用 active 的类/样式。
  • strict: 当为 true,要考虑位置是否匹配当前的URL时,pathname 尾部的斜线要考虑在内。
  • location 接收一个location对象,当url满足这个对象的条件才会跳转
  • isActive: 接收一个回调函数,只有当 active 状态变化时才能触发,如果返回false则跳转失败
<NavLink
  to="/login"
  activeStyle={{
    fontWeight: 'bold',
    color: 'red'
  }}
>
    <span>登录</span>
</NavLink>

或

const oddEvent = (match, location) => {
  if (!match) {
    return false
  }
  const eventID = parseInt(match.params.eventID)
  return !isNaN(eventID) && eventID % 2 === 1
}

<NavLink
  to="/login"
  isActive={oddEvent}
>login</NavLink>

 withRouter

withRouter 是一个高阶组件,可以将一个非路由组件包裹返回一个新的路由组件,使这个非路由组件也能访问到当前路由的 match、location、history 对象,同时还拥有非路由组件的特点。

import { Typography } from "antd";
// 高阶组件  把两个组件的优点合二为一 类似于手机和手机壳关系 
import { withRouter } from "react-router-dom/cjs/react-router-dom";

const Proimg11 = (props) => {
    return (
        <div onClick={() => props.history.push(`detail/${props.id}`)}>
            {
                props.size == 'large' ? (
                    <img src={props.imageSrc} height={285} width={490} alt="" />
                ) : (
                    <img src={props.imageSrc} height={120} width={240} alt="" />
                )
            }
            <div>
                <Typography.Text type="secondary">
                    {props.title.slice(0, 25)}
                </Typography.Text>
                <Typography.Text type="danger" strong>
                    ¥{props.price}起
                </Typography.Text>
            </div>
        </div>
    )
}

// 为什么 必须包裹withRouter才能生效 
export const Proimg = withRouter(Proimg11)
// withRouter  + Proimg11 两者优点合二为一 变成 Proimg 组件
// 将 withRouter 的逻辑和 Proimg11 的UI组合

路由的三种传参:params、search、state

params:

路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>

注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>

接收参数:this.props.match.params

search:

路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>

注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>

接收参数:this.props.location.search
// 接收search参数
import qs from 'querystring'
const {search} = this.props.location
const {id, title} = qs.parse(search.slice(1))

//备注:获取到的search是urlencoded编码字符串,需要借助querystring解析

let obj = {name: 'tom', age: 18}
console.log(qs.stringify((obj)));// name=tom&age=18  key=value&key=value (urlencoded)

let str = 'cartName=奔驰&price=199'
console.log(qs.parse(str));// {cartName: "奔驰", price: "199"}

state:

路由链接(携带参数):
<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>

注册路由(无需声明,正常注册即可):
<Route path="/demo/test" component={Test}/>

接收参数:this.props.location.state
//备注:刷新也可以保留住参数(hash路由刷新参数会丢失)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值