• React 全栈体系(十一)


    第五章 React 路由

    五、向路由组件传递参数数据

    1. 效果

    请添加图片描述

    2. 代码 - 传递 params 参数

    2.1 Message
    /* src/pages/Home/Message/index.jsx */
    import React, { Component } from "react";
    import {Link, Route} from 'react-router-dom'
    import Detail from './Detail'
    
    export default class Message extends Component {
      state = {
        messageArr: [
          {id:'01', title: '消息1'},
          {id:'02', title: '消息2'},
          {id:'03', title: '消息3'},
        ]
      }
      render() {
        const {messageArr} = this.state
        return (
          <div>
            <ul>
              {
                messageArr.map((msgObj)=>{
                  return (
                    <li key={msgObj.id}>
                      {/* 向路由组件传递params参数 */}
                      <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
                    </li>
                  )
                })
              }
            </ul>
            <hr />
            {/* 声明接收params参数 */}
            <Route path="/home/message/detail/:id/:title" component={Detail}/>
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    2.2 Detail
    /* src/pages/Home/Message/Detail/index.jsx */
    import React, { Component } from 'react'
    
    const Detaildata = [
        {id:'01', content:'你好,中国'},
        {id:'02', content:'你好,小帽学堂'},
        {id:'03', content:'你好,未来的自己'}
    ]
    export default class Detail extends Component {
      render() {
        //接收params参数
        const {id, title} = this.props.match.params
        const findResult = Detaildata.find((detailObj)=>{
            return detailObj.id === id
        })
        return (
          <ul>
            <li>ID:{id}</li>
            <li>Title:{title}</li>
            <li>Content: {findResult.content}</li>
          </ul>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3. 代码 - 传递 search 参数

    3.1 Message
    /* src/pages/Home/Message/index.jsx */
    import React, { Component } from "react";
    import {Link, Route} from 'react-router-dom'
    import Detail from './Detail'
    
    export default class Message extends Component {
      state = {
        messageArr: [
          {id:'01', title: '消息1'},
          {id:'02', title: '消息2'},
          {id:'03', title: '消息3'},
        ]
      }
      render() {
        const {messageArr} = this.state
        return (
          <div>
            <ul>
              {
                messageArr.map((msgObj)=>{
                  return (
                    <li key={msgObj.id}>
                      {/* 向路由组件传递params参数 */}
                      {/* {msgObj.title} */}
    
                      {/* 向路由组件传递search参数 */}
                      <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>
                    </li>
                  )
                })
              }
            </ul>
            <hr />
            {/* 声明接收params参数 */}
            {/*  */}
    
            {/* search参数无需声明接收,正常注册路由即可 */}
            <Route path="/home/message/detail" component={Detail}/>
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    3.2 Detail
    /* src/pages/Home/Message/Detail/index.jsx */
    import React, { Component } from 'react'
    import qs from 'querystring'
    
    const Detaildata = [
        {id:'01', content:'你好,中国'},
        {id:'02', content:'你好,小帽学堂'},
        {id:'03', content:'你好,未来的自己'}
    ]
    export default class Detail extends Component {
      render() {
        // 接收params参数
        // const {id, title} = this.props.match.params
    
        // 接收search参数
        const {search} = this.props.location
        const {id, title} = qs.parse(search.slice(1))
    
        const findResult = Detaildata.find((detailObj)=>{
            return detailObj.id === id
        })
        return (
          <ul>
            <li>ID:{id}</li>
            <li>Title:{title}</li>
            <li>Content: {findResult.content}</li>
          </ul>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    4. 代码 - 传递 state 参数

    4.1 Message
    /* src/pages/Home/Message/index.jsx */
    import React, { Component } from "react";
    import {Link, Route} from 'react-router-dom'
    import Detail from './Detail'
    
    export default class Message extends Component {
      state = {
        messageArr: [
          {id:'01', title: '消息1'},
          {id:'02', title: '消息2'},
          {id:'03', title: '消息3'},
        ]
      }
      render() {
        const {messageArr} = this.state
        return (
          <div>
            <ul>
              {
                messageArr.map((msgObj)=>{
                  return (
                    <li key={msgObj.id}>
                      {/* 向路由组件传递params参数 */}
                      {/* {msgObj.title} */}
    
                      {/* 向路由组件传递search参数 */}
                      {/* {msgObj.title} */}
    
                      {/* 向路由组件传递state参数 */}
                      <Link to={{pathname:'/home/message/detail', state:{id:msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link>
                    </li>
                  )
                })
              }
            </ul>
            <hr />
            {/* 声明接收params参数 */}
            {/*  */}
    
            {/* search参数无需声明接收,正常注册路由即可 */}
            {/*  */}
    
            {/* state参数无需声明接收,正常注册路由即可 */}
            <Route path="/home/message/detail" component={Detail}/>
    
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    4.2 Detail
    /* src/pages/Home/Message/Detail/index.jsx */
    import React, { Component } from 'react'
    // import qs from 'querystring'
    
    const Detaildata = [
        {id:'01', content:'你好,中国'},
        {id:'02', content:'你好,小帽学堂'},
        {id:'03', content:'你好,未来的自己'}
    ]
    export default class Detail extends Component {
      render() {
        // 接收params参数
        // const {id, title} = this.props.match.params
    
        // 接收search参数
        // const {search} = this.props.location
        // const {id, title} = qs.parse(search.slice(1))
    
        // 接收state参数
        const {id, title} = this.props.location.state || {}
        const findResult = Detaildata.find((detailObj)=>{
            return detailObj.id === id
        }) || {}
        return (
          <ul>
            <li>ID:{id}</li>
            <li>Title:{title}</li>
            <li>Content: {findResult.content}</li>
          </ul>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    5. 总结

    1.params参数
    	路由链接(携带参数)<Link to='/demo/test/tom/18'}>详情</Link>
    	注册路由(声明接收)<Route path="/demo/test/:name/:age" component={Test}/>
    	接收参数:this.props.match.params
    
    2.search参数
    	路由链接(携带参数)<Link to='/demo/test?name=tom&age=18'}>详情</Link>
    	注册路由(无需声明,正常注册即可)<Route path="/demo/test" component={Test}/>
    	接收参数:this.props.location.search
    	备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
    
    3.state参数
    	路由链接(携带参数)<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
    	注册路由(无需声明,正常注册即可)<Route path="/demo/test" component={Test}/>
    	接收参数:this.props.location.state
    	备注:刷新也可以保留住参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    6. 代码 - push 与 replace 模式

    Message
    /* src/pages/Home/Message/index.jsx */
    import React, { Component } from "react";
    import {Link, Route} from 'react-router-dom'
    import Detail from './Detail'
    
    export default class Message extends Component {
      state = {
        messageArr: [
          {id:'01', title: '消息1'},
          {id:'02', title: '消息2'},
          {id:'03', title: '消息3'},
        ]
      }
      render() {
        const {messageArr} = this.state
        return (
          <div>
            <ul>
              {
                messageArr.map((msgObj)=>{
                  return (
                    <li key={msgObj.id}>
                      {/* 向路由组件传递params参数 */}
                      {/* {msgObj.title} */}
    
                      {/* 向路由组件传递search参数 */}
                      {/* {msgObj.title} */}
    
                      {/* 向路由组件传递state参数 */}
                      <Link replace to={{pathname:'/home/message/detail', state:{id:msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link>
                    </li>
                  )
                })
              }
            </ul>
            <hr />
            {/* 声明接收params参数 */}
            {/*  */}
    
            {/* search参数无需声明接收,正常注册路由即可 */}
            {/*  */}
    
            {/* state参数无需声明接收,正常注册路由即可 */}
            <Route path="/home/message/detail" component={Detail}/>
    
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    六、多种路由跳转方式

    1. 效果

    请添加图片描述

    2. 代码 - 跳转 + 携带 params 参数

    2.1 Message
    /* src/pages/Home/Message/index.jsx */
    import React, { Component } from "react";
    import { Link, Route } from "react-router-dom";
    import Detail from "./Detail";
    
    export default class Message extends Component {
      state = {
        messageArr: [
          { id: "01", title: "消息1" },
          { id: "02", title: "消息2" },
          { id: "03", title: "消息3" },
        ],
      };
    
      pushShow = (id, title) => {
        //push跳转+携带params参数
        this.props.history.push(`/home/message/detail/${id}/${title}`)
      }
    
      replaceShow = (id, title) => {
        //replace跳转+携带params参数
        this.props.history.replace(`/home/message/detail/${id}/${title}`)
      }
      render() {
        const { messageArr } = this.state;
        return (
          <div>
            <ul>
              {messageArr.map((msgObj) => {
                return (
                  <li key={msgObj.id}>
                    {/* 向路由组件传递params参数 */}
                    <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>
                      {msgObj.title}
                    </Link>
                    &nbsp;<button onClick={()=>this.pushShow(msgObj.id, msgObj.title)}>push查看</button>
                    &nbsp;<button onClick={()=>this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button>
                  </li>
                );
              })}
            </ul>
            <hr />
            {/* 声明接收params参数 */}
            <Route path="/home/message/detail/:id/:title" component={Detail} />
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    2.2 Detail
    /* src/pages/Home/Message/Detail/index.jsx */
    import React, { Component } from 'react'
    // import qs from 'querystring'
    
    const Detaildata = [
        {id:'01', content:'你好,中国'},
        {id:'02', content:'你好,小帽学堂'},
        {id:'03', content:'你好,未来的自己'}
    ]
    export default class Detail extends Component {
      render() {
        // 接收params参数
        const {id, title} = this.props.match.params
    
        const findResult = Detaildata.find((detailObj)=>{
            return detailObj.id === id
        }) || {}
        return (
          <ul>
            <li>ID:{id}</li>
            <li>Title:{title}</li>
            <li>Content: {findResult.content}</li>
          </ul>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3. 代码 - 跳转 + 携带 state 参数

    3.1 Message
    /* src/pages/Home/Message/index.jsx */
    import React, { Component } from "react";
    import { Link, Route } from "react-router-dom";
    import Detail from "./Detail";
    
    export default class Message extends Component {
      state = {
        messageArr: [
          { id: "01", title: "消息1" },
          { id: "02", title: "消息2" },
          { id: "03", title: "消息3" },
        ],
      };
    
      pushShow = (id, title) => {
        //push跳转+携带state参数
        this.props.history.push(`/home/message/detail`, {id,title})
      }
    
      replaceShow = (id, title) => {
        //replace跳转+携带state参数
        this.props.history.replace(`/home/message/detail`, {id,title})
      }
      render() {
        const { messageArr } = this.state;
        return (
          <div>
            <ul>
              {messageArr.map((msgObj) => {
                return (
                  <li key={msgObj.id}>
                    {/* 向路由组件传递params参数 */}
                    <Link to={{pathname:'/home/message/detail',state:{id:msgObj.id, title:msgObj.title}}}>{msgObj.title}</Link>
                    &nbsp;<button onClick={()=>this.pushShow(msgObj.id, msgObj.title)}>push查看</button>
                    &nbsp;<button onClick={()=>this.replaceShow(msgObj.id, msgObj.title)}>replace查看</button>
                  </li>
                );
              })}
            </ul>
            <hr />
            {/* 声明接收state参数 */}
            <Route path="/home/message/detail" component={Detail} />
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    3.2 Detail
    /* src/pages/Home/Message/Detail/index.jsx */
    import React, { Component } from 'react'
    
    const Detaildata = [
        {id:'01', content:'你好,中国'},
        {id:'02', content:'你好,小帽学堂'},
        {id:'03', content:'你好,未来的自己'}
    ]
    export default class Detail extends Component {
      render() {
        const {id, title} = this.props.location.state
    
        const findResult = Detaildata.find((detailObj)=>{
            return detailObj.id === id
        })
        return (
          <ul>
            <li>ID:{id}</li>
            <li>Title:{title}</li>
            <li>Content: {findResult.content}</li>
          </ul>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    4. 代码 - 前进后退

    /* src/pages/Home/Message/index.jsx */
    import React, { Component } from "react";
    import { Link, Route } from "react-router-dom";
    import Detail from "./Detail";
    
    export default class Message extends Component {
      state = {
        messageArr: [
          { id: "01", title: "消息1" },
          { id: "02", title: "消息2" },
          { id: "03", title: "消息3" },
        ],
      };
    
      pushShow = (id, title) => {
        //push跳转+携带state参数
        this.props.history.push(`/home/message/detail`, { id, title });
      };
    
      replaceShow = (id, title) => {
        //replace跳转+携带state参数
        this.props.history.replace(`/home/message/detail`, { id, title });
      };
    
      back = () => {
        this.props.history.goBack();
      };
    
      forward = () => {
        this.props.history.goForward();
      };
    
      go = () => {
        this.props.history.go(-2);
      };
      render() {
        const { messageArr } = this.state;
        return (
          <div>
            <ul>
              {messageArr.map((msgObj) => {
                return (
                  <li key={msgObj.id}>
                    {/* 向路由组件传递params参数 */}
                    <Link
                      to={{
                        pathname: "/home/message/detail",
                        state: { id: msgObj.id, title: msgObj.title },
                      }}
                    >
                      {msgObj.title}
                    </Link>
                    &nbsp;
                    <button onClick={() => this.pushShow(msgObj.id, msgObj.title)}>
                      push查看
                    </button>
                    &nbsp;
                    <button
                      onClick={() => this.replaceShow(msgObj.id, msgObj.title)}
                    >
                      replace查看
                    </button>
                  </li>
                );
              })}
            </ul>
            <hr />
            {/* 声明接收state参数 */}
            <Route path="/home/message/detail" component={Detail} />
            <button onClick={this.back}>回退</button>&nbsp;
            <button onClick={this.forward}>前进</button>&nbsp;
            <button onClick={this.go}>go</button>
          </div>
        );
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    5. 总结

    借助this.prosp.history对象上的API对操作路由跳转、前进、后退
    	-this.prosp.history.push()
    	-this.prosp.history.replace()
    	-this.prosp.history.goBack()
    	-this.prosp.history.goForward()
    	-this.prosp.history.go()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    6. withRouter 的使用

    Header
    /* src/components/Header/index.jsx */
    import React, { Component } from 'react'
    import {withRouter} from 'react-router-dom'
    
    class Header extends Component {
    
    	back = ()=>{
    		this.props.history.goBack()
    	}
    
    	forward = ()=>{
    		this.props.history.goForward()
    	}
    
    	go = ()=>{
    		this.props.history.go(-2)
    	}
    
    	render() {
    		console.log('Header组件收到的props是',this.props);
    		return (
    			<div className="page-header">
    				<h2>React Router Demo</h2>
    				<button onClick={this.back}>回退</button>&nbsp;
    				<button onClick={this.forward}>前进</button>&nbsp;
    				<button onClick={this.go}>go</button>
    			</div>
    		)
    	}
    }
    
    export default withRouter(Header)
    
    //withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
    //withRouter的返回值是一个新组件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    请添加图片描述

    七、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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    Linux 下的 /proc 目录介绍
    python代码实现生成二维码
    HTML5+CSS网页作业:汽车介绍特斯拉 (dreamweaver作业静态HTML网页设计模板)
    大学生川菜网页制作教程 学生HTML静态美食菜品网页设计作业成品 简单网页制作代码 学生美食网页作品免费设计
    duilib 进阶 之 list 容器使用 及扩展
    初步探索GraalVM——云原生时代JVM黑科技
    分布式计算框架——MapReduce
    ubuntu软件安装和管理(apt-get)
    上市一年,市值惨跌八成!大模型救不了智云健康
    『C语言』深度走入取整 & 4种函数
  • 原文地址:https://blog.csdn.net/sgsgkxkx/article/details/133103018