React-router学习笔记 react-router基本使用

和Vue有vue-router来管理路由一样,React中也有一个用于管理路由的react-router,基本的使用也是差不多的,下面通过一个项目的简单搭建来学习基本的使用方法

搭建项目

首先使用create-react-app脚手架搭建一个项目,搭建完成后将react-router,react-router-dom安装到本地项目

create-react-app mydemo

cnpm i react-router --save
cnpm i react-router-dom --save

接下来我们将src中的文件清空,自己重新来写一下

编写基本的路由

首先新建index.js,导入我们需要的各种内容

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router,Route,Link } from 'react-router-dom'

这里是要在web下运行,导入了BrowserRouter并命名为Router,接下里写一个组件来render到页面上

class AppRouter extends React.Component{
    render(){
        return (
            <div>here is AppRouter</div>
        )
    }
}

ReactDOM.render(<AppRouter />, document.getElementById('root'))

此时运行npm run start我们就能看到页面上的here is AppRouter了,接下来就是编写路由和路由对应的组件了
在react-router中,我们通过从react-router-dom中拿到的Link来做跳转,Route来做对应匹配哪个组件显示,这与vue-router中的router-link和router-view类似,不同的是,vue-router中的router-link和router-view可以和其他标签放的位置一样,而Link和Route却只能放在Router中,否则就会报错
正确的写法如下

class AppRouter extends React.Component{
    render(){
        return(
            <Router>
                <li>
                    <Link to="/">HOME</Link>
                </li>
                <li>
                    <Link  to="/about">ABOUT</Link>
                </li>
                <li>
                    <Link  to="/topics">TOPICS</Link>
                </li>
                {/* exact:精确匹配,为布尔值,默认为false,即不做精确匹配 */}
                {/* 需要完全匹配的时候才使用exact */}
                <Route exact path="/" component={Home} />
                <Route exact path="/about" component={About} />
                <Route exact path="/topics" component={Topics} />
            </Router>
        )
    }
}

然后我们编写相应的组件

class Home extends React.Component{
    render(){
        return(
            <div>this is Home page</div>
        )
    }
}

class About extends React.Component{
    render(){
        return (
            <div>this is About page</div>
        )
    }
}

class Topics extends React.Component{
    render(){
        return (
            <div>this is Topics page</div>
        )
    }
}

到这里就可以在页面上显示对应的内容并且做跳转了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里就算基本完成了,我们回到上面说的,如果我们不将Link和Route放在Router中,会发生什么呢

class AppRouter extends React.Component{
    render(){
        return(
            // 将Router替换成div
            <div>
                <li>
                    <Link to="/">HOME</Link>
                </li>
                <li>
                    <Link  to="/about">ABOUT</Link>
                </li>
                <li>
                    <Link  to="/topics">TOPICS</Link>
                </li>
                <Route exact path="/" component={Home} />
                <Route exact path="/about" component={About} />
                <Route exact path="/topics" component={Topics} />
            </div>
        )
    }
}

就会出现下面的报错
在这里插入图片描述
解决这个问题后,我们将Link和Route分别放在两个不同的组件,为了减少多余的父组件,这里使用fragments的短语法<></>

class AppRouter extends React.Component{
    render(){
        return(
            <Router>
                <RouterLink />
                <RouterShow />
            </Router>
        )
    }
}

class RouterLink extends React.Component{
    render(){
        return(
            <>
                <li>
                    <Link to="/">HOME</Link>
                </li>
                <li>
                    <Link  to="/about">ABOUT</Link>
                </li>
                <li>
                    <Link  to="/topics">TOPICS</Link>
                </li>
            </>
        )
    }
}

class RouterShow extends React.Component{
    render(){
        return(
            <> 
                {/* exact:精确匹配 */}
                {/* 需要完全匹配的时候才使用exact */}
                <Route exact path="/" component={Home} />
                <Route path="/about" component={About} />
                <Route path="/topics" component={Topics} />
            </>
        )
    }
}

Route的属性

接下来看看上面Route使用的两个属性exact和path,在vscode中可以直接按住ctrl点击Route标签看看这个组件的源代码
可以看到以下内容

export interface RouteProps {
  location?: H.Location;
  component?: React.ComponentType<RouteComponentProps<any>> | React.ComponentType<any>;
  render?: ((props: RouteComponentProps<any>) => React.ReactNode);
  children?: ((props: RouteChildrenProps<any>) => React.ReactNode) | React.ReactNode;
  path?: string | string[];
  exact?: boolean;
  sensitive?: boolean;
  strict?: boolean;
}
export class Route<T extends RouteProps = RouteProps> extends React.Component<T, any> { }

exact上面已经在代码的注释里面看到了,它是一个布尔值,告诉我们是否精确匹配,我们看到上面代码里面,About组件对应的路由是没用精确匹配的,所以下面的路由也可以显示About组件
在这里插入图片描述
而一旦修改为精确匹配
在这里插入图片描述
我们发现它已经匹配不到About组件了,这就是exact
说说path,显然path就是用来写路由,而componentj就是路由对应的组件,我们看到,在上面的代码中path是可以使用字符串和字符串数组的,也即是说,同一个组件,可以匹配多个路由,只要使用数组的形式来写就可以

<Route path={["/about",'/about1']} component={About} />

发现/about和/about1都可以显示About组件

发布了178 篇原创文章 · 获赞 12 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zemprogram/article/details/102396313