react路由深度解析
先看一段代碼能否秒懂很重要
這是app.js 全局js的入口
import React from 'react'
import { render } from 'react-dom'
import { Router, browserHistory } from 'react-router' import withExampleBasename from '../withExampleBasename'
import './stubs/COURSES' const rootRoute = {
childRoutes: [ { //子路由
path: '/',
component: require('./components/App'),
childRoutes: [
require('./routes/Calendar'), //當前目錄下有這么幾個子路由
require('./routes/Course'),
require('./routes/Grades'),
require('./routes/Messages'),
require('./routes/Profile')
]
} ]
} render((
<Router
history={withExampleBasename(browserHistory, __dirname)}
routes={rootRoute}
/>
), document.getElementById('example'))
以上面的calendar為例子 calendar下面有component 和index.js 同樣其他如course grades等下面也一樣
index.js
module.exports = {
path: 'calendar',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./components/Calendar'))
})
}
}
component下面有calendar.js
import React, { Component } from 'react'
class Calendar extends Component {
render() {
const events = [
{ id: 0, title: 'essay due' }
]
return (
<div>
<h2>Calendar</h2>
<ul>
{events.map(event => (
<li key={event.id}>{event.title}</li>
))}
</ul>
</div>
)
}
}
module.exports = Calendar
怎么樣找到訣竅了嗎 /routes/calendar/index.js +component/calendar.js /routes/grades/index.js +component/grades.js
找到規律了吧 !!
來一個稍微復雜的路由
(這是全局的變量入口) COURSE.JS
global.COURSES = [
{
id: 0,
name: 'React Fundamentals',
grade: 'B',
announcements: [
{
id: 0,
title: 'No class tomorrow',
body: 'There is no class tomorrow, please do not show up'
}
],
assignments: [
{
id: 0,
title: 'Build a router',
body: 'It will be easy, seriously, like 2 hours, 100 lines of code, no biggie',
grade: 'N/A'
}
] }, {
id: 1,
name: 'Reusable React Components',
grade: 'A-',
announcements: [
{
id: 0,
title: 'Final exam next wednesday',
body: 'You had better prepare'
}
],
assignments: [
{
id: 0,
title: 'PropTypes',
body: 'They aren\'t for you.',
grade: '80%'
},
{
id: 1,
title: 'Iterating and Cloning Children',
body: 'You can totally do it.',
grade: '95%'
}
]
}
]
Course路由下面有子路由 他的目錄結構 /routes/course/index.js +component(course.js+nav.js+dashborad.js)+ routers/(assignments + announcement +grade.js)
瞬間有點凌亂 有木有 往下看就明白了
course.js
/*globals COURSES:true */
import React, { Component } from 'react'
import Dashboard from './Dashboard'
import Nav from './Nav' const styles = {} styles.sidebar = {
float: 'left',
width: 200,
padding: 20,
borderRight: '1px solid #aaa',
marginRight: 20
} class Course extends Component {
render() {
let { sidebar, main, children, params } = this.props
let course = COURSES[params.courseId] //這是啥? 根據前面導航條轉過來的
let content
if (sidebar && main) { //根據條件 初始化組件內容
content = (
<div>
<div className="Sidebar" style={styles.sidebar}>
{sidebar}
</div>
<div className="Main" style={{ padding: 20 }}>
{main}
</div>
</div>
)
} else if (children) {
content = children
} else {
content = <Dashboard /> //走的是這一步
} return (
<div>
<h2>{course.name}</h2>
<Nav course={course} /> //吸進來的一個組件 確定是去哪里 announcement assignment grades
{content}
</div>
)
}
} module.exports = Course
貌似還有點迷糊 繼續往下看吧
nav.js
import React, { Component } from 'react'
import { Link } from 'react-router'
const styles = {}
styles.nav = {
borderBottom: '1px solid #aaa'
}
styles.link = {
display: 'inline-block',
padding: 10,
textDecoration: 'none'
}
styles.activeLink = {
...styles.link,
color: 'red'
}
class Nav extends Component {
render() {
const { course } = this.props
const pages = [
[ 'announcements', 'Announcements' ],
[ 'assignments', 'Assignments' ],
[ 'grades', 'Grades' ]
]
return (
<nav style={styles.nav}>
{pages.map((page, index) => (
<Link
key={page[0]}
activeStyle={index === 0 ? { ...styles.activeLink, paddingLeft: 0 } : styles.activeLink}
style={index === 0 ? { ...styles.link, paddingLeft: 0 } : styles.link}
to={`/course/${course.id}/${page[0]}`} //這里是3個導航的跳轉 /course/${course.id}/announcement 去往announcements assignments grades
>{page[1]}</Link>
))}
</nav>
)
}
}
export default Nav
來看一下router/announcement(index.js + component + router)
index.js 文件
module.exports = {
path: 'announcements',
getChildRoutes(partialNextState, cb) {
require.ensure([], (require) => {
cb(null, [
require('./routes/Announcement') //這又是一個子路由
])
})
},
getComponents(nextState, cb) {
require.ensure([], (require) => {
cb(null, {
sidebar: require('./components/Sidebar'),
main: require('./components/Announcements') //依賴的組件
})
})
}
}
看到這里是否有點明白了 就像洋蔥一層一層撥動我的心。。。還沒完呢
component/announcement.js
import React, { Component } from 'react'
class Announcements extends Component {
render() {
return (
<div>
<h3>Announcements</h3>
{this.props.children || <p>Choose an announcement from the sidebar.</p>} //這個props在哪里找呀
</div>
)
}
}
module.exports = Announcements
component/sidebar.js
import React, { Component } from 'react'
import { Link } from 'react-router'
class AnnouncementsSidebar extends Component {
render() {
let { announcements } = COURSES[this.props.params.courseId] //注意這種es6的語法 取得是里面announcements的直
return (
<div>
<h3>Sidebar Assignments</h3>
<ul>
{announcements.map(announcement => (
<li key={announcement.id}>
<Link to={`/course/${this.props.params.courseId}/announcements/${announcement.id}`}>
{announcement.title} //這個到了最后了
</Link>
</li>
))}
</ul>
</div>
)
}
}
module.exports = AnnouncementsSidebar
還沒完呢 還有個 router-anouncement /index.js + announcement.js 的路由
看index.js 里面的內容
module.exports = {
path: ':announcementId', //終于真相大白了 !!
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./components/Announcement'))
})
}
}
在看最里面的組件announcement.js
import React, { Component } from 'react'
class Announcement extends Component {
render() {
let { courseId, announcementId } = this.props.params //這個很關鍵 怎么著呢 說白了就是 地址的參數 ${courseId} ${announceId}
let { title, body } = COURSES[courseId].announcements[announcementId]
return (
<div>
<h4>{title}</h4>
<p>{body}</p>
</div>
)
}
}
module.exports = Announcement
我們大概可以看出來 這個路由到底是如何運作了 還有些細節問題我們繼續看
整理一下思路 再出發
1. 第一個app.js 確定根目錄 /
2. /calendar /course /message /profile 這都是二級目錄 下面都有一個 index.js 指定當前的路徑 如course/index.js 指定path:course;
3./course/${courseiD}/announcement/${announcementId} /course/${courseiD}/assignment/${assignmentId} 這是 深層次的
4./course/calendar course/grades 這是淺層次的
最后是關鍵的全局組件
app.js
import React, { Component } from 'react'
import Dashboard from './Dashboard'
import GlobalNav from './GlobalNav'
class App extends Component {
render() {
return (
<div>
<GlobalNav />
<div style={{ padding: 20 }}>
{this.props.children || <Dashboard courses={COURSES} />} //如果該屬性沒有children 就render dashboard
</div>
</div>
)
}
}
module.exports = App
dashboard.js
import React, { Component } from 'react'
import { Link } from 'react-router'
class Dashboard extends Component {
render() {
const { courses } = this.props
return (
<div>
<h2>Super Scalable Apps</h2>
<p>
Open the network tab as you navigate. Notice that only the amount of
your app that is required is actually downloaded as you navigate
around. Even the route configuration objects are loaded on the fly.
This way, a new route added deep in your app will not affect the
initial bundle of your application.
</p>
<h2>Courses</h2>{' '}
<ul>
{courses.map(course => (
<li key={course.id}>
<Link to={`/course/${course.id}`}>{course.name}</Link> //這里會根據當前id去不同的course頁面
</li>
))}
</ul>
</div>
)
}
}
export default Dashboard
globalNav.js 全局導航
import React, { Component } from 'react'
import { Link } from 'react-router'
const dark = 'hsl(200, 20%, 20%)'
const light = '#fff'
const styles = {}
styles.wrapper = {
padding: '10px 20px',
overflow: 'hidden',
background: dark,
color: light
}
styles.link = {
padding: 11,
color: light,
fontWeight: 200
}
styles.activeLink = {
...styles.link,
background: light,
color: dark
}
class GlobalNav extends Component {
constructor(props, context) {
super(props, context)
this.logOut = this.logOut.bind(this)
}
logOut() {
alert('log out')
}
render() {
const { user } = this.props
return (
<div style={styles.wrapper}>
<div style={{ float: 'left' }}>
<Link to="/" style={styles.link}>Home</Link>{' '} // 回到根目錄
<Link to="/calendar" style={styles.link} activeStyle={styles.activeLink}>Calendar</Link>{' '}
<Link to="/grades" style={styles.link} activeStyle={styles.activeLink}>Grades</Link>{' '}
<Link to="/messages" style={styles.link} activeStyle={styles.activeLink}>Messages</Link>{' '}
</div>
<div style={{ float: 'right' }}>
<Link style={styles.link} to="/profile">{user.name}</Link> <button onClick={this.logOut}>log out</button>
</div>
</div>
)
}
}
GlobalNav.defaultProp= {
user: {
id: 1,
name: 'Ryan Florence'
}
}
export default GlobalNav
好吧 現在頭緒出來了吧 我反正有點眉目了
1.首先是index.html 有個globalnav / /calendar /grades /message /profile 分別去向 主頁 日歷頁 年級頁 信息頁 詳情頁
2.如果 找不到props.children 就會渲染course 也會根據當前的courseid去往相應頁
好吧 今天就這么多 讓我好好捋捋。。。
總結
以上是生活随笔為你收集整理的react路由深度解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SIM900A 发送AT+CSTT 总
- 下一篇: byte[],bitmap,drawab