这篇博客是,基于react hook的脚手架,配合react-router-config react-router-dom来搭建的路由结构,简介,结构清晰,方便管理。。。
demo已经发布到github上
感觉可以的点一点star,谢谢咯!
写过vue的小伙伴都知道,vue的路由是在new Router 里统一配置的,写起来也特别爽,路由层次很清除,也很方便管理,然而react的路由相比较而言就有局限性,也不方便管理。
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
let roles = [
{
path: '/',
component: home,
redirect: '/home/first',
children: allroutes()
},
{
path: '/login',
component: login
},
{
path: '*',
redirect: '/'
}
]
const router = new Router({
routes: roles
})
import React from 'react'
import {
Router, Route, Link } from 'react-router'
const App = React.createClass({
render() {
return (
<div>
<h1>App</h1>
<ul>
<li><Link to="/about">About</Link></li>
<li><Link to="/inbox">Inbox</Link></li>
</ul>
{
this.props.children}
</div>
)
}
})
const About = React.createClass({
render() {
return <h3>About</h3>
}
})
const Inbox = React.createClass({
render() {
return (
<div>
<h2>Inbox</h2>
{
this.props.children || "Welcome to your Inbox"}
</div>
)
}
})
const Message = React.createClass({
render() {
return <h3>Message {
this.props.params.id}</h3>
}
})
React.render((
<Router>
<Route path="/" component={
App}>
<Route path="about" component={
About} />
<Route path="inbox" component={
Inbox}>
<Route path="messages/:id" component={
Message} />
</Route>
</Route>
</Router>
), document.body)
而且4.0版本之前的react router中Router标签里不能嵌套其他标签,路由的灵活性就大打折扣,而且路由层次不清,尤其设计的路由嵌套的时候,看着也很乱。
1.搭个react基本项目
npm install -g create-react-app
create-react-app my-app
cd my-app/
npm start
2.安装我们需要的包
npm install react-router-config react-router-dom
//看package.json是否成功
3.创建目录结构
路由可以跟写vue一样,层次分明,统一配置
import AllComponent from '../components'
import Home from '../components/Home'
import Child from '../components/Childs'
import First from '../components/Childs/First'
import Second from '../components/Childs/Second'
import Other from '../components/Other'
import Setting from '../components/Set'
const routes = [ {
path: '/',
component: AllComponent,//当组件下有子组件的时候要特别注意
routes: [ {
path: '/home',
component: Home,
routes: [],
},
{
path: '/child',
component: Child,
routes: [ {
path: '/child/first',
component: First,
routes: []
},
{
path: '/child/second',
component: Second,
routes: []
}
],
},
{
path: '/other',
component: Other,
routes: [],
},
{
path: '/set',
component: Setting,
routes: [],
},
],
},
]
export default routes
这里用的react-router-config,目的就是省去了我们遍历routes为Route标签的过程,
import React from 'react'
import {
renderRoutes } from 'react-router-config'
import {
BrowserRouter } from 'react-router-dom'
import routes from './allroutes'
const Router = () => (
<BrowserRouter>{
renderRoutes(routes)}</BrowserRouter>
//这个方法,每次有子路由时都需要使用,会传当前路由的子路由,可以说是按需加载,
//实时编译的,而不是一次性吧所有路由都渲染出来
)
export default Router
上面的renderRoutes(routes),就是代替了下面的遍历过程。
{routes.map((route, i) => (
{
if (!route.requiresAuth || authed || route.path === authPath) {
return
}
return
}}
/>
))}
这里就是正常的菜单,想在哪渲染就引入就好
import React, {
memo } from 'react'
import {
Link } from 'react-router-dom'
export default memo(function Sider() {
return (
<div className="route">
<Link to="/home">首页</Link>
<Link to="/child">孩子</Link>
<Link to="/other">其他</Link>
<Link to="/set">设置</Link>
</div>
)
})
import React, {
memo ,useEffect} from 'react'
import {
renderRoutes } from 'react-router-config'
import {
withRouter} from 'react-router-dom'
import Sider from './Sider'
export default memo(withRouter(function AllComponent(props) {
console.log(props.route,'props.route',props.location)
//这里可以使用react-router-dom里的,useLocation 和 useHistory 方法
useEffect(() => {
if(props.location.pathname === '/'){
props.history.push('/home')
}
}, [props.location.pathname])
return (
<div>
<Sider />
<div className="content">
{
renderRoutes(props.route.routes)
//这个方法,每次有子路由时都需要使用,会传当前路由的子路由,可以说是按需加载,
//实时编译的,而不是一次性吧所有路由都渲染出来
}
</div>
</div>
)
}))
childs文件夹也是路由嵌套的,所以也用了renderRoutes(),就相当于,要渲染路由儿子,需要你指定儿子路由的位置。
import React, {
memo ,useEffect } from 'react'
import {
renderRoutes } from 'react-router-config'
import {
Link } from 'react-router-dom'
import {
withRouter} from 'react-router-dom'
export default memo(withRouter(function Index(props) {
console.log(props.route.routes,'props.route.routes')
useEffect(() => {
if(props.location.pathname === '/child'){
props.history.push('/child/first')
}
}, [props.location.pathname])
return (
<div>
<div className="secondroute">
<Link to="/child/first">第一个孩子</Link>
<Link to="/child/second">第二个孩子</Link>
</div>
<div className="content">
{
renderRoutes(props.route.routes)}
//这个方法,每次有子路由时都需要使用,会传当前路由的子路由,可以说是按需加载,
//实时编译的,而不是一次性吧所有路由都渲染出来
</div>
</div>
)
}))
类似于这样的一个简单的基础组件
import React, {
memo } from 'react'
export default memo(function Other() {
return (
<div className="content">
other
</div>
)
})
demo已经发布到github上
感觉可以的点一点star,谢谢咯!