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'), //當(dāng)前目錄下有這么幾個(gè)子路由
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
找到規(guī)律了吧 ??!
來(lái)一個(gè)稍微復(fù)雜的路由
(這是全局的變量入口) 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路由下面有子路由 他的目錄結(jié)構(gòu) /routes/course/index.js +component(course.js+nav.js+dashborad.js)+ routers/(assignments + announcement +grade.js)
瞬間有點(diǎn)凌亂 有木有 往下看就明白了
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] //這是啥? 根據(jù)前面導(dǎo)航條轉(zhuǎn)過(guò)來(lái)的
let content
if (sidebar && main) { //根據(jù)條件 初始化組件內(nèi)容
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} /> //吸進(jìn)來(lái)的一個(gè)組件 確定是去哪里 announcement assignment grades
{content}
</div>
)
}
} module.exports = Course
貌似還有點(diǎn)迷糊 繼續(xù)往下看吧
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個(gè)導(dǎo)航的跳轉(zhuǎn) /course/${course.id}/announcement 去往announcements assignments grades
>{page[1]}</Link>
))}
</nav>
)
}
}
export default Nav
來(lái)看一下router/announcement(index.js + component + router)
index.js 文件
module.exports = {
path: 'announcements',
getChildRoutes(partialNextState, cb) {
require.ensure([], (require) => {
cb(null, [
require('./routes/Announcement') //這又是一個(gè)子路由
])
})
},
getComponents(nextState, cb) {
require.ensure([], (require) => {
cb(null, {
sidebar: require('./components/Sidebar'),
main: require('./components/Announcements') //依賴的組件
})
})
}
}
看到這里是否有點(diǎn)明白了 就像洋蔥一層一層撥動(dòng)我的心。。。還沒(méi)完呢
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>} //這個(gè)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的語(yǔ)法 取得是里面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} //這個(gè)到了最后了
</Link>
</li>
))}
</ul>
</div>
)
}
}
module.exports = AnnouncementsSidebar
還沒(méi)完呢 還有個(gè) router-anouncement /index.js + announcement.js 的路由
看index.js 里面的內(nèi)容
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 //這個(gè)很關(guān)鍵 怎么著呢 說(shuō)白了就是 地址的參數(shù) ${courseId} ${announceId}
let { title, body } = COURSES[courseId].announcements[announcementId]
return (
<div>
<h4>{title}</h4>
<p>{body}</p>
</div>
)
}
}
module.exports = Announcement
我們大概可以看出來(lái) 這個(gè)路由到底是如何運(yùn)作了 還有些細(xì)節(jié)問(wèn)題我們繼續(xù)看
整理一下思路 再出發(fā)
1. 第一個(gè)app.js 確定根目錄 /
2. /calendar /course /message /profile 這都是二級(jí)目錄 下面都有一個(gè) index.js 指定當(dāng)前的路徑 如course/index.js 指定path:course;
3./course/${courseiD}/announcement/${announcementId} /course/${courseiD}/assignment/${assignmentId} 這是 深層次的
4./course/calendar course/grades 這是淺層次的
最后是關(guān)鍵的全局組件
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} />} //如果該屬性沒(méi)有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> //這里會(huì)根據(jù)當(dāng)前id去不同的course頁(yè)面
</li>
))}
</ul>
</div>
)
}
}
export default Dashboard
globalNav.js 全局導(dǎo)航
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
好吧 現(xiàn)在頭緒出來(lái)了吧 我反正有點(diǎn)眉目了
1.首先是index.html 有個(gè)globalnav / /calendar /grades /message /profile 分別去向 主頁(yè) 日歷頁(yè) 年級(jí)頁(yè) 信息頁(yè) 詳情頁(yè)
2.如果 找不到props.children 就會(huì)渲染course 也會(huì)根據(jù)當(dāng)前的courseid去往相應(yīng)頁(yè)
好吧 今天就這么多 讓我好好捋捋。。。
總結(jié)
以上是生活随笔為你收集整理的react路由深度解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SIM900A 发送AT+CSTT 总
- 下一篇: byte[],bitmap,drawab