react路由基础与传参

react-router-dom

1、react的一个插件,专门用来实现单页面。

2、基于react的项目基本都会用到它。

路由的基本使用

1、路由导航区标签为Link或NavLink标签

<Link to="/xxx">xxx</Link>

<NavLink to="/xxx">xxx</NavLink>

NavLink标签会为当前匹配路由添加"active"类名,我们可以通过activeClassName来更改它的默认类名

tips:所有组件体的内容可以通过this.props.children获取,如果标签属性children也是可以通过 this.props.children获取。

eg: <NavLink to="/xxx">xxx</NavLink>等同于<NavLink to="/xxx" children="xxx" />

2、路由展示区写Route标签进行路径匹配

<Route path="/xxx" component={xxx}>

3、App外侧包裹一个<BrowserRouter> 或 <HashRouter>

import './App.css';
import Hello from "./component/hello/index"
import Bea from "./component/bea/index"
import { Link,NavLink, BrowserRouter, Route } from "react-router-dom";
function App() {
  return (
    <div className="App">
      {/* 需要包裹路由,需要包裹在最外层,最好的做法是直接包裹App组件 */}
      <BrowserRouter>
        <p>react router!</p>
        {/* <Hello name='deng'/>
      <Bea /> */}
        <div className='list'>
          {/* <Link className='item-link' to="/bea">bea组件</Link>
          <Link className='item-link' to="/hello">hello组件</Link> */}

          <NavLink className='item-link' activeClassName='routeActive' to="/bea">bea组件</NavLink>
          <NavLink className='item-link' activeClassName='routeActive' to="/hello">hello组件</NavLink>
        </div>
        <div className='show-area'>
          {/* 注册路由 */}

          <Route path="/bea" component={Bea}></Route>
          <Route path="/hello" component={Hello}></Route>

        </div>
      </BrowserRouter>
    </div>

  );
}

export default App;

路由组件和一般组件

1.写法不同

一般组件:<Demo />

路由组件:<Route path="/demo" component={Demo} />

2.存放位置不同

一般组件:components

路由组件:pages

3.接收到的props不同

一般组件:写组件标签时传递了什么,就能接收到什么

路由组件:接收到三个固定的属性history location match

switch的使用

当写了多个相同的路由时,react会将路由对应的组件全部显示出来。可以用switch包裹路由,这样react匹配到一个路由后就不会再继续匹配了。

不使用switch时:

使用switch时:

import './App.css';
import Hello from "./component/hello/index"
import Bea from "./component/bea/index"
import { Link, NavLink, Switch, BrowserRouter, Route } from "react-router-dom";
function App() {
  return (
    <div className="App">
      {/* 需要包裹路由,需要包裹在最外层,最好的做法是直接包裹App组件 */}
      <BrowserRouter>
        <p>react router!</p>
        {/* <Hello name='deng'/>
      <Bea /> */}
        <div className='list'>
          {/* <Link className='item-link' to="/bea">bea组件</Link>
          <Link className='item-link' to="/hello">hello组件</Link> */}

          <NavLink className='item-link' activeClassName='routeActive' to="/bea">bea组件</NavLink>
          <NavLink className='item-link' activeClassName='routeActive' to="/hello">hello组件</NavLink>

        </div>
        <div className='show-area'>
          {/* 注册路由 */}
          <Switch>
            <Route path="/bea" component={Bea}></Route>
            <Route path="/hello" component={Hello}></Route>
            <Route path="/hello" component={Hello}></Route>
          </Switch>
        </div>
      </BrowserRouter>
    </div>

  );
}

export default App;

路由的严格匹配和模糊匹配

react路由匹配默认为模糊匹配,即/bea/a是能匹配到/bea的,但是/a/bea无法匹配到/bea,需要满足最左匹配。

设置exact为true可开启严格匹配

<Route exact path="/bea" component={Bea}></Route>

注意:严格匹配模式不要随便开启,需要再开,因为有时候开启可能会导致无法匹配二级路由。

Redirect的使用

Redirect组件需要放在注册路由的最底部,表示路由未匹配到时,跳转到指定的路由。

import './App.css';
import Hello from "./component/hello/index"
import Bea from "./component/bea/index"
import { Link, NavLink, Switch, BrowserRouter, Route, Redirect } from "react-router-dom";
function App() {
  return (
    <div className="App">
      {/* 需要包裹路由,需要包裹在最外层,最好的做法是直接包裹App组件 */}
      <BrowserRouter>
        <p>react router!</p>
        <div className='row'>
          <div className="col-md-4 row-item">.col-md-4</div>
          <div className="col-md-4 row-item">.col-md-4</div>
          <div className="col-md-4 row-item">.col-md-4</div>
        </div>
        {/* <Hello name='deng'/>
      <Bea /> */}
        <div className='list'>
          {/* <Link className='item-link' to="/bea">bea组件</Link>
          <Link className='item-link' to="/hello">hello组件</Link> */}

          <NavLink className='item-link' activeClassName='routeActive' to="/a/bea">bea组件</NavLink>
          <NavLink className='item-link' activeClassName='routeActive' to="/a/hello">hello组件</NavLink>

        </div>
        <div className='show-area'>
          {/* 注册路由 */}
          <Switch>
            <Route path="/a/bea" component={Bea}></Route>
            <Route path="/a/hello" component={Hello}></Route>
            <Route path="/a/hello" component={Hello}></Route>
            <Redirect to="/a/bea" />
          </Switch>
        </div>
      </BrowserRouter>
    </div>

  );
}
export default App;

嵌套路由

1、注册子路由时要加上父路由path值

2、路由的匹配是按照注册路由的顺序进行的

向路由组件传递参数

方法一:传递params参数

在跳转路由(Link、NavLink)路径后面,以路径的格式传递params参数,然后在路由展示组件(Route)path属性中通过“/:xxx”的形式申明要接收的params参收。这样在路由对应的组件内就可以props.match.params中传递的路由参数了。

import React, { Component } from "react";
import Details from './details/index';
import { Link, Route } from 'react-router-dom';

export default class Message extends Component {
    state = {
        messageList: [
            { id: 1, name: '消息1:江西加油!' },
            { id: 2, name: '消息2:广东加油!' },
            { id: 3, name: '消息3:江苏加油!' },
        ]
    };
    render() {
        const { messageList } = this.state;
        return (
            <div>
                {
                    messageList.map(ele => {
                        return <p style={{
                            textAlign: 'left'
                        }} key={ele.id}>
                            {/* 向路由组件传递参数 */}
                            <Link to={`/hello/message/detail/${ele.id}/${ele.name}`}>{ele.name}</Link>
                        </p>
                    })
                }
                {/* 申明接收参数 */}
                <Route path='/hello/message/detail/:id/:name' component={Details}></Route >
            </div>
        )
    }
}
import React, { Component } from 'react'

const messageList = [
    { id: 1, content: '明天会更好!' },
    { id: 2, content: '我相信我就是我!' },
    { id: 3, content: '你可以的!' },
]
export default class Details extends Component {
    render() {
        //接收路由传递的参数
        const { id, name } = this.props.match.params;
        const content = messageList.find(ele => {
            return ele.id == id;
        })
        return (
            <div>
                <p>ID: {id}</p>
                <p>{name}</p>
                <p>内容:{content.content}</p>
            </div>
        )
    }
}

方法二:传递search参数

通过在Link或者NavLink组件中以urlencode的方式传递参数,这样在路由对应的组件内就可以props.location.search中接收传递的路由参数了。

import React, { Component } from "react";
import Details from './details/index';
import { Link, Route } from 'react-router-dom';

export default class Message extends Component {
    state = {
        messageList: [
            { id: 1, name: '消息1:江西加油!' },
            { id: 2, name: '消息2:广东加油!' },
            { id: 3, name: '消息3:江苏加油!' },
        ]
    };
    render() {
        const { messageList } = this.state;
        return (
            <div>
                {
                    messageList.map(ele => {
                        return <p style={{
                            textAlign: 'left'
                        }} key={ele.id}>
                            {/* 向路由组件传递search参数 */}
                            <Link to={`/hello/message/detail?id=${ele.id}&name=${ele.name}`}>{ele.name}</Link>
                        </p>
                    })
                }

                {/* search无需申明接收 */}
                <Route path='/hello/message/detail' component={Details}></Route >
            </div>
        )
    }
}

获取到的search参数是未解析好的,可以用react已经下好的qs模块来解析urlencode编码字符串

import React, { Component } from 'react'
import qs from "qs";
const messageList = [
    { id: 1, content: '明天会更好!' },
    { id: 2, content: '我相信我就是我!' },
    { id: 3, content: '你可以的!' },
]
export default class Details extends Component {
    render() {
        //接收路由search参数
        const searchStr = this.props.location.search;
        const search = qs.parse(searchStr.slice(1));
        const content = messageList.find(ele => {
            return ele.id == search.id;
        })
        return (
            <div>
                <p>ID: {search.id}</p>
                <p>{search.name}</p>
                <p>内容:{content.content}</p>
            </div>
        )
    }
}

方法三:传递state参数

通过在Link或者NavLink组件中,to传递一个对象,pathname属性为跳转路径,state为传递的路由参数

import React, { Component } from "react";
import Details from './details/index';
import { Link, Route } from 'react-router-dom';

export default class Message extends Component {
    state = {
        messageList: [
            { id: 1, name: '消息1:江西加油!' },
            { id: 2, name: '消息2:广东加油!' },
            { id: 3, name: '消息3:江苏加油!' },
        ]
    };
    render() {
        const { messageList } = this.state;
        return (
            <div>
                {
                    messageList.map(ele => {
                        return <p style={{
                            textAlign: 'left'
                        }} key={ele.id}>
                            {/* 向路由组件传递state参数 */}
                            <Link to={{ pathname: `/hello/message/detail`, state: { id: ele.id, name: ele.name } }}>{ele.name}</Link>
                        </p>
                    })
                }
                 {/* state无需申明接收 */}
                <Route path='/hello/message/detail' component={Details}></Route >
            </div>
        )
    }
}

通过props.location.state接收传递的参数

import React, { Component } from 'react'
import qs from "qs";
const messageList = [
    { id: 1, content: '明天会更好!' },
    { id: 2, content: '我相信我就是我!' },
    { id: 3, content: '你可以的!' },
]
export default class Details extends Component {
    render() {
        //接收路由state参数
        const state = this.props.location.state;
        const content = messageList.find(ele => {
            return ele.id == state.id;
        })
        return (
            <div>
                <p>ID: {state.id}</p>
                <p>{state.name}</p>
                <p>内容:{content.content}</p>
            </div>
        )
    }
}

总结:三种传递路由参数的方式都挺常用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值