每天学点React - NavLink与封装NavLink

236 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第27天,点击查看活动详情

前言

在上一篇《每天学点React - React路由入门》中,我们用到了Link 组件来实现导航区的一个路由跳转触发点,但是这个有一个问题就是对于用户选择了哪一个菜单,显示得并不是很清晰,所以,我们需要采用一个更好的组件NavLink,该组件有一个属性active可以用来激活样式。

NavLink

基本使用

import React, { Component } from 'react'
import { NavLink, Route } from 'react-router-dom'

import Home from './pages/Home'
import About from './pages/About'
import Header from './components/Header'

export default class App extends Component {
    render() {
        return (
            <div id='root'>
                <div>
                    <div className='row'>
                        <div className='col-xs-offset-2 col-xs-8'>
                            <Header></Header>
                        </div>
                    </div>
                    <div className='row'>
                        <div className='col-xs-2 col-xs-offset-2'>
                            <div className='list-group'>
                                {/* 在React中靠路由链接实现切换组件--定义路由链接 */}
                                <NavLink activeClassName='myActiveCss' className='list-group-item' to='/about'>About</NavLink>
                                <NavLink activeClassName='myActiveCss' className='list-group-item' to='/home'>Home</NavLink>
                            </div>
                        </div>
                        <div className='col-xs-6'>
                            <div className='panel'>
                                <div className='panel-body'>
                                    <Route path='/about' component={About}></Route>
                                    <Route path='/home' component={Home}></Route>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

我们在NavLink标签中添加了activeClassName属性指定了样式,在效果图中可以看到当前页的展示在左侧的导航栏中有了显眼的提示。

image.png

封装NavLink

NavLink已经能实现导航区的样式展示了,但是我们一般的导航菜单会有十几乃至几十项,如果都一行行的添加相同的属性,那会显得代码非常冗余。我们可以自己把该组件封装多一层,把所有的通用点统一管理起来。至于不同的点,则使用props进行参数传递即可。

代码实现

App

import React, { Component } from 'react'
import { Route } from 'react-router-dom'

import Home from './pages/Home'
import About from './pages/About'
import Header from './components/Header'
import MyNavLink from './components/MyNavLink'

export default class App extends Component {
    render() {
        return (
            <div id='root'>
                <div>
                    <div className='row'>
                        <div className='col-xs-offset-2 col-xs-8'>
                            <Header></Header>
                        </div>
                    </div>
                    <div className='row'>
                        <div className='col-xs-2 col-xs-offset-2'>
                            <div className='list-group'>
                                {/* 自定义路径标签,可以便于统一样式 */}
                                <MyNavLink to='/about'>About</MyNavLink>
                                <MyNavLink to='/home'>Home</MyNavLink>
                            </div>
                        </div>
                        <div className='col-xs-6'>
                            <div className='panel'>
                                <div className='panel-body'>
                                    <Route path='/about' component={About}></Route>
                                    <Route path='/home' component={Home}></Route>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

MyNavLink

import React, { Component } from 'react'
import {NavLink} from 'react-router-dom'

export default class MyNavLink extends Component {
  render() {
    console.log(this.props)
    return (
        <NavLink className='list-group-item' {...this.props}/>
    )
  }
}

image.png

在上图中可以看到,我们将MyNavLink组件接收到的参数传递进来之后,将传递的to属性打印了出来,但是还多了一个children属性,这个是哪里来的呢?我们看看外面的自定义标签,有哪个能对应上。

image.png

在图中标签体内圈起来的黄色框框部分,正好对应上来children属性的值,原来它将我们标签体内的内容通过children属性传递了进来,我们如果要获取标签体类的值,可以通过该属性来获取。这样,我们只需要在封装的MyNavLink组件中直接填写props参数即可。