Commit 69f5c1b7 by Wee

refactor: amend comment and abstract function

parent 2354c91b
......@@ -6,10 +6,10 @@ import matchPath from './matchPath'
import ReactDOM from 'react-dom'
const isEmptyChildren = children => React.Children.count(children) === 0
const NORMAL_RENDER_MATCH = 'normal matched render'
const NORMAL_RENDER_UNMATCH = 'normal unmatched render (unmount)'
const NORMAL_RENDER_INIT = 'normal render'
const HIDE_RENDER = 'hide route when matched'
const NORMAL_RENDER_MATCHED = 'normal matched render'
const NORMAL_RENDER_UNMATCHED = 'normal unmatched render (unmount)'
const NORMAL_RENDER_ON_INIT = 'normal render (matched or unmatched)'
const HIDE_RENDER = 'hide route when livePath matched'
/**
* The public API for matching a single path and rendering.
*/
......@@ -25,7 +25,8 @@ class Route extends React.Component {
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
location: PropTypes.object,
livePath: PropTypes.string,
alwaysLive: PropTypes.bool
alwaysLive: PropTypes.bool,
name: PropTypes.string // for LiveRoute debug
}
static contextTypes = {
......@@ -56,7 +57,7 @@ class Route extends React.Component {
match: this.computeMatch(this.props, this.context.router)
}
liveState = NORMAL_RENDER_INIT
liveState = NORMAL_RENDER_ON_INIT
scrollPosBackup = null
previousDisplayStyle = null
......@@ -77,11 +78,10 @@ class Route extends React.Component {
)
}
// 获取 Route 对应的 DOM
componentDidMount() {
// 需要在这里模仿 cwrp 保存一下 router
// backup router and get DOM when mounting
if (this.doesRouteEnableLive() && this.state.match) {
this._prevRouter = this.context.router
this._latestMatchedRouter = this.context.router
this.getRouteDom()
}
}
......@@ -100,7 +100,7 @@ class Route extends React.Component {
let match = this.computeMatch(nextProps, nextContext.router)
let computedMatch = match
// 如果是 live 路由,需要重新计算 match
// recompute match if enable live
if (this.doesRouteEnableLive()) {
computedMatch = this.computeMatchWithLive(this.props, nextProps, nextContext, match)
}
......@@ -116,20 +116,21 @@ class Route extends React.Component {
return
}
// 是正常的显示渲染
// restore display when matched normally
console.log(this.liveState)
if (this.liveState === NORMAL_RENDER_MATCH) {
if (this.liveState === NORMAL_RENDER_MATCHED) {
this.showRoute()
this.restoreScroll()
this.restoreScrollPosition()
this.clearScroll()
}
// 正常渲染标记 DOM
// get DOM if match and render
if (this.state.match) {
this.getRouteDom()
}
}
// clear on unmounting
componentWillUnmount() {
this.clearScroll()
}
......@@ -142,52 +143,52 @@ class Route extends React.Component {
* @param {*} props: this.props
* @param {*} nextProps: nextProps
* @param {*} nextContext: nextContext
* @param {*} match: 当前路径的 match
* @param {*} match: computed `match` of current path
* @returns
* 如果当前的 path 匹配,则返回正常的 match。
* 如果当前的 livePath 匹配,则返回最近一次正常渲染的 match。
* 如果当前的 livePath 不匹配,则返回正常计算的 match。
* the returned object will be computed by following orders:
* If path matched (no matter livePath matched or not), return normal computed `match`
* If livePath matched, return latest normal render `match`
* If livePath unmatched, return normal computed `match`
* @memberof Route
* 在每次正常渲染的时候,都备份它当前的 router,备份给下一次的 livePath 渲染。
* 在每次隐藏渲染的时候,都返回一个 prevMatch,等到渲染的时候,它拿这次的 prevMatch 和之前的 router 去最终渲染。
* Back up current router every time it is rendered normally, backing up to the next livePath rendering
*/
computeMatchWithLive(props, nextProps, nextContext, match) {
console.log(`>>>>>> ` + this.props.name + ` <<<<<`)
// 计算 livePath 是否匹配
console.log(`>>> ` + this.props.name + ` <<<`)
// compute if livePath match
const livePath = nextProps.livePath
const nextPropsWithLivePath = { ...nextProps, path: livePath }
const prevMatch = this.computeMatch(props, this.context.router)
const livePathMatch = this.computeMatch(nextPropsWithLivePath, nextContext.router)
if (match) {
// 匹配正常渲染
console.log('---- NORMAL MATCH FLAG ----')
this.liveState = NORMAL_RENDER_MATCH
// normal matched render
console.log('--- NORMAL MATCH FLAG ---')
this.liveState = NORMAL_RENDER_MATCHED
return match
} else if ((livePathMatch || props.alwaysLive) && this.routeDom) {
// 在从正常渲染到隐藏的时候备份 router
// backup router when from normal match render to hide render
if (prevMatch) {
this._prevRouter = this.context.router
this._latestMatchedRouter = this.context.router
}
// 隐藏渲染
console.log('---- HIDE FLAG----')
// hide render
console.log('--- HIDE FLAG ---')
this.liveState = HIDE_RENDER
this.saveScroll()
this.saveScrollPosition()
this.hideRoute()
return prevMatch
} else {
// 不匹配正常卸载
console.log('---- NORMAL UNMATCH FLAG----')
this.liveState = NORMAL_RENDER_UNMATCH
this.routeDom = null
this.scrollPosBackup = null
this.previousDisplayStyle = null
// normal unmatched unmount
console.log('--- NORMAL UNMATCH FLAG ---')
this.liveState = NORMAL_RENDER_UNMATCHED
this.clearScroll()
this.clearDomData()
}
}
computeMatch({ computedMatch, location, path, strict, exact, sensitive }, router) {
// react-live-route: ignore match from <Switch>, actually LiveRoute should not be wrapped by <Switch>.
// if (computedMatch) return computedMatch // <Switch> already computed the match for us
// DO NOT use the computedMatch from Switch!
// if (computedMatch) return computedMatch // <Switch> already computed the match for us
invariant(router, 'You should not use <Route> or withRouter() outside a <Router>')
const { route } = router
......@@ -196,13 +197,13 @@ class Route extends React.Component {
return matchPath(pathname, { path, strict, exact, sensitive }, route.match)
}
// 获取 Route 对应的 DOM
// get DOM of Route
getRouteDom() {
let routeDom = ReactDOM.findDOMNode(this)
this.routeDom = routeDom
}
// 隐藏 DOM 并保存 scroll
// backup scroll and hide DOM
hideRoute() {
if (this.routeDom && this.routeDom.style.display !== 'none') {
console.log('--- hide route ---')
......@@ -211,15 +212,15 @@ class Route extends React.Component {
}
}
// 显示 DOM 并恢复 scroll
// reveal DOM display
showRoute() {
if (this.routeDom && this.previousDisplayStyle !== null) {
this.routeDom.style.display = this.previousDisplayStyle
}
}
// 保存离开前的 scroll
saveScroll() {
// save scroll position before hide DOM
saveScrollPosition() {
if (this.routeDom && this.scrollPosBackup === null) {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
const scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft
......@@ -228,8 +229,8 @@ class Route extends React.Component {
}
}
// 恢复离开前的 scroll
restoreScroll() {
// restore the scroll position before hide
restoreScrollPosition() {
const scroll = this.scrollPosBackup
console.log(scroll)
if (scroll && this.routeDom) {
......@@ -237,14 +238,22 @@ class Route extends React.Component {
}
}
// 清除 scroll
// clear scroll position
clearDomData() {
if (this.doesRouteEnableLive()) {
this.routeDom = null
this.previousDisplayStyle = null
}
}
// clear scroll position
clearScroll() {
if (this.doesRouteEnableLive()) {
this.scrollPosBackup = null
}
}
// 正常渲染 component 或 render
// normally render or unmount Route
renderRoute(component, render, props, match) {
console.log(match)
if (component) return match ? React.createElement(component, props) : null
......@@ -257,20 +266,19 @@ class Route extends React.Component {
const { history, route, staticContext } = this.context.router
const location = this.props.location || route.location
const props = { match, location, history, staticContext }
if ((livePath || alwaysLive) && (component || render)) {
console.log('=== RENDER FLAG: ' + this.liveState + ' ===')
if (
this.liveState === NORMAL_RENDER_MATCH ||
this.liveState === NORMAL_RENDER_UNMATCH ||
this.liveState === NORMAL_RENDER_INIT
this.liveState === NORMAL_RENDER_MATCHED ||
this.liveState === NORMAL_RENDER_UNMATCHED ||
this.liveState === NORMAL_RENDER_ON_INIT
) {
// 正常渲染
// normal render
return this.renderRoute(component, render, props, match)
} else if (this.liveState === HIDE_RENDER) {
// 隐藏渲染
const prevRouter = this._prevRouter
// 取出 prevRouter 中的属性 mock 出上次正常渲染的 props
// hide render
const prevRouter = this._latestMatchedRouter
// load properties from prevRouter and fake props of latest normal render
const { history, route, staticContext } = prevRouter
const location = this.props.location || route.location
const liveProps = { match, location, history, staticContext }
......@@ -278,7 +286,7 @@ class Route extends React.Component {
}
}
// 以下是 Route 的正常渲染
// the following is the same as Route of react-router, just render it normally
if (component) return match ? React.createElement(component, props) : null
if (render) return match ? render(props) : null
......
{
"name": "react-live-route",
"version": "1.1.16",
"version": "1.1.17",
"description": "A living route for react-router-v4",
"repository": "fi3ework/react-live-route",
"license": "MIT",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment