使用react-router进行多级路由匹配

React-router学习笔记 react-router基本使用中,我做了精确的路由匹配,但是实际上,我们在进行路由匹配的时候,一般是会进行多级路由的匹配,所以这里说说如何进行多级路由的匹配

在使用react-router-dom的Link的时候,我们需要使用to来指定路由,而Route用来显示路由对应得内容,默认情况下,Route 会进行路由的模糊匹配

<Route path="/topics" component={Topics}></Route>

上面的这个Route,在路由为/topics时可以显示,在路由为/topics/str时也可以显示(str随机的字符串),所以我们可以利用这个特点,让该Route对应的组件在显示多级路由内容时也可以显示
简单的代码如下

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

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(
            <> 
                <Route exact path="/" component={Home} />
                <Route exact path="/about" component={About} />
                <Route path="/topics" component={Topics} />
            </>
        )
    }
}

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

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

class Topics extends React.Component{
    render(){
        return (
            <div>
                <h1>this is Topics page</h1>
                <hr/>
                <div>
                    <li>
                        <Link to="/topics/topic1">topic1</Link>
                    </li>
                    <li>
                        <Link  to="/topics/topic2">topic2</Link>
                    </li>
                    <li>
                        <Link  to="/topics/topic3">topic3</Link>
                    </li>
                </div>
                <hr/>
                <div>
                    <Route path="/topics/topic1" component={Topic1}/>
                    <Route path="/topics/topic2" component={Topic2} />
                    <Route path="/topics/topic3" component={Topic3}/>
                </div>
            </div>
        )
    }
}

class Topic1 extends React.Component{
    render(){
        return <p>here is topic1</p>
    }
}
class Topic2 extends React.Component{
    render(){
        return <p>here is topic2</p>
    }
}
class Topic3 extends React.Component{
    render(){
        return <p>here is topic3</p>
    }
}

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

上面的代码固然实现了效果,但是显然,很多内容显得过于冗余了,三个子Topic组件看起来很是类似,只是显示的内容有点不一样,我们是不是可以尝试使用一个组件,然后在父组件传值进来显示呢,答案当然是可以的,我们可以通过props来获取父组件的内容,也可以通过props来获取url的内容
我们将Topic1组件修改成下面这样子,打印出props

class Topic1 extends React.Component{
    constructor(props){
        super(props);
        console.log(props)
    }
    render(){
        return <p>here is topic1</p>
    }
}

观察打印内容,可以看到props.match中就有相应的路由,我们可以通过获取对应的url,来修改子组件的内容(这里url和path是一样的,使用path的理由会在下面提及)
在这里插入图片描述
但是这样子的话,我们还需要将path对应的字符串的前缀路由去掉,才能匹配到我们真正想要的topic1,我们要想个办法来更好地获取我们要的内容
在Route中,我们可以通过:的写法,来将路由对应的内容,反映到params的属性上,我们修改三个Route

<Route path="/topics/:topicName" component={Topic1}/>
<Route path="/topics/:topicName" component={Topic2} />
<Route path="/topics/:topicName" component={Topic3}/>

重新看以下控制台的打印内容
在这里插入图片描述
我们发现,params已经不再是一个空对象了,而且里面的属性的key,正是我们写在:后面的内容,而key对应的内容,正是子路由的内容
同时这里我们也看到了path和url的不同了,url是真实的路由,而path是我们写在Route上的path属性的值。
回归正题,既然我们可以通过这种方式来获得想应的内容,那我们就可以对我们写的代码进行优化了,将三个子Topic组件合成一个,获取props.match的内容来修改子组件的内容,三个Route也可以合成一个了

<Route path="/topics/:topicName" component={Topic}/>

class Topic extends React.Component{
    constructor(props){
        super(props);
        console.log(props)
    }
    render(){
        return <p>here is {this.props.match.params.topicName}</p>
    }
}

这部分优化完后,我们看看别的部分,我们发现,每次写子组件时,都要记住父组件对应的路由,写在每个Link和Route里面,万一路由进行修改,那相关的子组件也要修改,很不利于维护,所以我们要采用别的方式
其实我们要做的和上面是一样的,通过props的内容来进行路由跳转,我们将props的内容写入Link和Route中,要注意的是在Link中写入path,在Route中写入url,实际上文档中也这么写了
在这里插入图片描述
所以修改代码如下

class Topics extends React.Component{
    render(){
        return (
            <div>
                <h1>this is Topics page</h1>
                <hr/>
                <div>
                    
                    <li>
                        <Link to={`${this.props.match.path}/topic1`}>topic1</Link>
                    </li>
                    <li>
                        <Link to={`${this.props.match.path}/topic2`}>topic2</Link>
                    </li>
                    <li>
                        <Link to={`${this.props.match.path}/topic3`}>topic3</Link>
                    </li>
                </div>
                <hr/>
                <div>
                    <Route path={`${this.props.match.url}/:topicName`} component={Topic}/>
                </div>
            </div>
        )
    }
}

至此基本完成多级路由匹配的优化

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

猜你喜欢

转载自blog.csdn.net/zemprogram/article/details/102463567
今日推荐