Commit 9e6b616f by Wee

temp: before eject

parent 68375a1c
...@@ -30,10 +30,13 @@ import ReactDOM from 'react-dom'; ...@@ -30,10 +30,13 @@ import ReactDOM from 'react-dom';
import { matchPath } from 'react-router'; import { matchPath } from 'react-router';
import { isValidElementType } from 'react-is'; import { isValidElementType } from 'react-is';
var isEmptyChildren = function (children) { return React.Children.count(children) === 0; }; var isEmptyChildren = function (children) { return React.Children.count(children) === 0; };
var NORMAL_RENDER_MATCHED = 'normal matched render'; var LiveState;
var NORMAL_RENDER_UNMATCHED = 'normal unmatched render (unmount)'; (function (LiveState) {
var NORMAL_RENDER_ON_INIT = 'normal render (matched or unmatched)'; LiveState["NORMAL_RENDER_MATCHED"] = "normal matched render";
var HIDE_RENDER = 'hide route when livePath matched'; LiveState["NORMAL_RENDER_UNMATCHED"] = "normal unmatched render (unmount)";
LiveState["NORMAL_RENDER_ON_INIT"] = "normal render (matched or unmatched)";
LiveState["HIDE_RENDER"] = "hide route when livePath matched";
})(LiveState || (LiveState = {}));
/** /**
* The public API for matching a single path and rendering. * The public API for matching a single path and rendering.
*/ */
...@@ -45,7 +48,7 @@ var LiveRoute = /** @class */ (function (_super) { ...@@ -45,7 +48,7 @@ var LiveRoute = /** @class */ (function (_super) {
_this.state = { _this.state = {
match: _this.computeMatch(_this.props, _this.context.router) match: _this.computeMatch(_this.props, _this.context.router)
}; };
_this.liveState = NORMAL_RENDER_ON_INIT; _this.liveState = LiveState.NORMAL_RENDER_ON_INIT;
_this.scrollPosBackup = null; _this.scrollPosBackup = null;
_this.previousDisplayStyle = null; _this.previousDisplayStyle = null;
return _this; return _this;
...@@ -90,7 +93,7 @@ var LiveRoute = /** @class */ (function (_super) { ...@@ -90,7 +93,7 @@ var LiveRoute = /** @class */ (function (_super) {
} }
// restore display when matched normally // restore display when matched normally
console.log(this.liveState); console.log(this.liveState);
if (this.liveState === NORMAL_RENDER_MATCHED) { if (this.liveState === LiveState.NORMAL_RENDER_MATCHED) {
this.showRoute(); this.showRoute();
this.restoreScrollPosition(); this.restoreScrollPosition();
this.clearScroll(); this.clearScroll();
...@@ -130,7 +133,7 @@ var LiveRoute = /** @class */ (function (_super) { ...@@ -130,7 +133,7 @@ var LiveRoute = /** @class */ (function (_super) {
if (match) { if (match) {
// normal matched render // normal matched render
console.log('--- NORMAL MATCH FLAG ---'); console.log('--- NORMAL MATCH FLAG ---');
this.liveState = NORMAL_RENDER_MATCHED; this.liveState = LiveState.NORMAL_RENDER_MATCHED;
return match; return match;
} }
else if ((livePathMatch || props.alwaysLive) && this.routeDom) { else if ((livePathMatch || props.alwaysLive) && this.routeDom) {
...@@ -140,7 +143,7 @@ var LiveRoute = /** @class */ (function (_super) { ...@@ -140,7 +143,7 @@ var LiveRoute = /** @class */ (function (_super) {
} }
// hide render // hide render
console.log('--- HIDE FLAG ---'); console.log('--- HIDE FLAG ---');
this.liveState = HIDE_RENDER; this.liveState = LiveState.HIDE_RENDER;
this.saveScrollPosition(); this.saveScrollPosition();
this.hideRoute(); this.hideRoute();
return prevMatch; return prevMatch;
...@@ -148,7 +151,7 @@ var LiveRoute = /** @class */ (function (_super) { ...@@ -148,7 +151,7 @@ var LiveRoute = /** @class */ (function (_super) {
else { else {
// normal unmatched unmount // normal unmatched unmount
console.log('--- NORMAL UNMATCH FLAG ---'); console.log('--- NORMAL UNMATCH FLAG ---');
this.liveState = NORMAL_RENDER_UNMATCHED; this.liveState = LiveState.NORMAL_RENDER_UNMATCHED;
this.clearScroll(); this.clearScroll();
this.clearDomData(); this.clearDomData();
} }
...@@ -252,13 +255,13 @@ var LiveRoute = /** @class */ (function (_super) { ...@@ -252,13 +255,13 @@ var LiveRoute = /** @class */ (function (_super) {
var props = { match: match, location: location, history: history, staticContext: staticContext }; var props = { match: match, location: location, history: history, staticContext: staticContext };
if ((livePath || alwaysLive) && (component || render)) { if ((livePath || alwaysLive) && (component || render)) {
console.log('=== RENDER FLAG: ' + this.liveState + ' ==='); console.log('=== RENDER FLAG: ' + this.liveState + ' ===');
if (this.liveState === NORMAL_RENDER_MATCHED || if (this.liveState === LiveState.NORMAL_RENDER_MATCHED ||
this.liveState === NORMAL_RENDER_UNMATCHED || this.liveState === LiveState.NORMAL_RENDER_UNMATCHED ||
this.liveState === NORMAL_RENDER_ON_INIT) { this.liveState === LiveState.NORMAL_RENDER_ON_INIT) {
// normal render // normal render
return this.renderRoute(component, render, props, match); return this.renderRoute(component, render, props, match);
} }
else if (this.liveState === HIDE_RENDER) { else if (this.liveState === LiveState.HIDE_RENDER) {
// hide render // hide render
var prevRouter = this._latestMatchedRouter; var prevRouter = this._latestMatchedRouter;
// load properties from prevRouter and fake props of latest normal render // load properties from prevRouter and fake props of latest normal render
......
# example demo
demo based on create-react-app
run:
```bash
npm install
npm start
```
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -18,4 +18,4 @@ ...@@ -18,4 +18,4 @@
"test": "react-scripts test --env=jsdom", "test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject" "eject": "react-scripts eject"
} }
} }
\ No newline at end of file
import React from "react"; import React from 'react'
class ListPage extends React.Component { class ListPage extends React.Component {
state = { count: 0 }; state = { count: 0 }
componentDidMount() { componentDidMount() {
window.scrollTo(0, 0); window.scrollTo(0, 0)
setInterval(() => { setInterval(() => {
this.setState({ this.setState({
count: this.state.count + 1 count: this.state.count + 1
}); })
}, 200); }, 200)
} }
render() { render() {
const timer = <h2 className="count">count: {this.state.count}</h2>; const timer = <h2 className="count">count: {this.state.count}</h2>
const desc = ( const desc = (
<div className="desc"> <div className="desc">
<p> <p>
This page of route is using <code>LiveRoute</code> with{" "} This page of route is using <code>LiveRoute</code> with <code>alwaysLive</code>.
<code>alwaysLive</code>.
</p>
<p>
It will not unmount after mounted and that means it will only mount
once.
</p> </p>
<p>It will not unmount after mounted and that means it will only mount once.</p>
</div> </div>
); )
const placeholder = Array(60) const placeholder = Array(60)
.fill("") .fill('')
.map((item, index) => { .map((item, index) => {
return ( return (
<p className="placeholder-text" key={index}> <p className="placeholder-text" key={index}>
{index} - You can scroll the screen to test if react-live-route can {index} - You can scroll the screen to test if react-live-route can restore scroll position.
restore scroll position.
</p> </p>
); )
}); })
return ( return (
<div className="about"> <div className="about">
{timer} {timer}
{desc} {desc}
{placeholder} {placeholder}
</div> </div>
); )
} }
} }
export default ListPage; export default ListPage
import React from "react"; import React from 'react'
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom'
import "./styles.css"; import './styles.css'
const Bar = props => { const Bar = props => {
return ( return (
...@@ -9,7 +9,7 @@ const Bar = props => { ...@@ -9,7 +9,7 @@ const Bar = props => {
<Link to="/items">Items</Link> <Link to="/items">Items</Link>
<Link to="/about">About</Link> <Link to="/about">About</Link>
</div> </div>
); )
}; }
export default Bar; export default Bar
import React from "react"; import React from 'react'
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom'
const List = props => { const List = props => {
return ( return (
...@@ -7,23 +7,15 @@ const List = props => { ...@@ -7,23 +7,15 @@ const List = props => {
<Link to="/items"> <Link to="/items">
<div>&gt;&gt; back to List</div> <div>&gt;&gt; back to List</div>
</Link> </Link>
<div className="detailContent">{`hello, I'm item - ${ <div className="detailContent">{`hello, I'm item - ${props.match.params.id}`}</div>
props.match.params.id <Link className="pagination" to={`/item/${Number.parseInt(props.match.params.id) - 1}`}>
}`}</div>
<Link
className="pagination"
to={`/item/${Number.parseInt(props.match.params.id) - 1}`}
>
Prev item Prev item
</Link> </Link>
<Link <Link className="pagination" to={`/item/${Number.parseInt(props.match.params.id) + 1}`}>
className="pagination"
to={`/item/${Number.parseInt(props.match.params.id) + 1}`}
>
Next item Next item
</Link> </Link>
</div> </div>
); )
}; }
export default List; export default List
import React from "react"; import React from 'react'
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom'
const Home = props => { const Home = props => {
return ( return (
...@@ -16,7 +16,7 @@ const Home = props => { ...@@ -16,7 +16,7 @@ const Home = props => {
<div className="entry">into items</div> <div className="entry">into items</div>
</Link> </Link>
</div> </div>
); )
}; }
export default Home; export default Home
import React from "react"; import React from 'react'
import ReactDOM from "react-dom"; import ReactDOM from 'react-dom'
import { Route, BrowserRouter } from "react-router-dom"; import { Route, BrowserRouter } from 'react-router-dom'
import LiveRoute from "react-live-route"; import LiveRoute from '../../dist/index'
import List from "./list"; import List from './list'
import Detail from "./detail"; import Detail from './detail'
import Bar from "./bar"; import Bar from './bar'
import About from "./about"; import About from './about'
import Home from "./home"; import Home from './home'
import "./styles.css"; import './styles.css'
function App() { function App() {
return ( return (
<div className="App"> <div className="App">
<Route exact path="/" component={Home} /> <Route exact path="/" component={Home} />
<LiveRoute <LiveRoute path="/items" component={List} livePath="/item/:id" name="items" />
path="/items"
component={List}
livePath="/item/:id"
name="items"
/>
<Route path="/item/:id" component={Detail} /> <Route path="/item/:id" component={Detail} />
<LiveRoute <LiveRoute path="/about" alwaysLive={true} component={About} name="about" />
path="/about"
alwaysLive={true}
component={About}
name="about"
/>
<Bar /> <Bar />
</div> </div>
); )
} }
const rootElement = document.getElementById("root"); const rootElement = document.getElementById('root')
ReactDOM.render( ReactDOM.render(
<BrowserRouter> <BrowserRouter>
<App /> <App />
</BrowserRouter>, </BrowserRouter>,
rootElement rootElement
); )
if ("scrollRestoration" in window.history) { if ('scrollRestoration' in window.history) {
// 默认值为'auto' // 默认值为 'auto'
// window.history.scrollRestoration = 'manual' // window.history.scrollRestoration = 'manual'
} }
document.addEventListener("scrollTo", () => { document.addEventListener('scrollTo', () => {
console.log("233"); console.log('233')
}); })
import React from "react"; import React from 'react'
import { Link } from "react-router-dom"; import { Link } from 'react-router-dom'
class ListPage extends React.Component { class ListPage extends React.Component {
state = { count: 0 }; state = { count: 0 }
componentWillUnmount() { componentWillUnmount() {
console.log("##### items will unmount #####"); console.log('##### items will unmount #####')
} }
componentDidMount() { componentDidMount() {
console.log("##### items did mount #####"); console.log('##### items did mount #####')
window.scrollTo(0, 0); window.scrollTo(0, 0)
setInterval(() => { setInterval(() => {
this.setState({ this.setState({
count: this.state.count + 1 count: this.state.count + 1
}); })
}, 200); }, 200)
} }
render() { render() {
const list = Array(200) const list = Array(200)
.fill("") .fill('')
.map((item, index) => { .map((item, index) => {
return ( return (
<Link className="item" to={`/item/${index}`} key={index}> <Link className="item" to={`/item/${index}`} key={index}>
<div>Item - {index}</div> <div>Item - {index}</div>
</Link> </Link>
); )
}); })
const timer = <h2 className="count">count: {this.state.count}</h2>; const timer = <h2 className="count">count: {this.state.count}</h2>
const desc = ( const desc = (
<div className="desc"> <div className="desc">
<p> <p>
This page of route is using <code>LiveRoute</code> with{" "} This page of route is using <code>LiveRoute</code> with <code>livePath</code>.
<code>livePath</code>.
</p> </p>
<p> <p>
In this page, the list page will not be unmounted on item detail page In this page, the list page will not be unmounted on item detail page and will be unmounted when enter into
and will be unmounted when enter into other pages such as home page. other pages such as home page.
</p> </p>
<p> <p>
The count number above is a sign of component live state. It will be The count number above is a sign of component live state. It will be reset to 0 when the component of Route
reset to 0 when the component of Route unmounted. You can scroll the unmounted. You can scroll the page and it will be restored when backing from item detail page.
page and it will be restored when backing from item detail page.
</p> </p>
<p>Feel free to try it.</p> <p>Feel free to try it.</p>
</div> </div>
); )
return ( return (
<div className="list"> <div className="list">
{timer} {timer}
{desc} {desc}
{list} {list}
</div> </div>
); )
} }
} }
export default ListPage; export default ListPage
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
"sideEffects": false, "sideEffects": false,
"scripts": { "scripts": {
"build": "rm -fr dist && tsc", "build": "rm -fr dist && tsc",
"watch": "tsc -b -w --pretty", "dev": "tsc -b -w --pretty",
"prepare": "npm run build", "prepare": "npm run build",
"lint": "eslint modules", "lint": "eslint modules",
"test": "jest" "test": "jest"
......
...@@ -7,10 +7,13 @@ import { matchPath } from 'react-router' ...@@ -7,10 +7,13 @@ import { matchPath } from 'react-router'
import { isValidElementType } from 'react-is' import { isValidElementType } from 'react-is'
const isEmptyChildren = children => React.Children.count(children) === 0 const isEmptyChildren = children => React.Children.count(children) === 0
const NORMAL_RENDER_MATCHED = 'normal matched render'
const NORMAL_RENDER_UNMATCHED = 'normal unmatched render (unmount)' enum LiveState {
const NORMAL_RENDER_ON_INIT = 'normal render (matched or unmatched)' NORMAL_RENDER_MATCHED = 'normal matched render',
const HIDE_RENDER = 'hide route when livePath matched' NORMAL_RENDER_UNMATCHED = 'normal unmatched render (unmount)',
NORMAL_RENDER_ON_INIT = 'normal render (matched or unmatched)',
HIDE_RENDER = 'hide route when livePath matched'
}
type CacheDom = HTMLElement | null type CacheDom = HTMLElement | null
...@@ -86,7 +89,7 @@ class LiveRoute extends React.Component<IProps, any> { ...@@ -86,7 +89,7 @@ class LiveRoute extends React.Component<IProps, any> {
match: this.computeMatch(this.props as any, this.context.router) match: this.computeMatch(this.props as any, this.context.router)
} }
liveState = NORMAL_RENDER_ON_INIT liveState: LiveState = LiveState.NORMAL_RENDER_ON_INIT
scrollPosBackup: { left: number; top: number } | null = null scrollPosBackup: { left: number; top: number } | null = null
previousDisplayStyle: string | null = null previousDisplayStyle: string | null = null
...@@ -147,7 +150,7 @@ class LiveRoute extends React.Component<IProps, any> { ...@@ -147,7 +150,7 @@ class LiveRoute extends React.Component<IProps, any> {
// restore display when matched normally // restore display when matched normally
console.log(this.liveState) console.log(this.liveState)
if (this.liveState === NORMAL_RENDER_MATCHED) { if (this.liveState === LiveState.NORMAL_RENDER_MATCHED) {
this.showRoute() this.showRoute()
this.restoreScrollPosition() this.restoreScrollPosition()
this.clearScroll() this.clearScroll()
...@@ -191,7 +194,7 @@ class LiveRoute extends React.Component<IProps, any> { ...@@ -191,7 +194,7 @@ class LiveRoute extends React.Component<IProps, any> {
if (match) { if (match) {
// normal matched render // normal matched render
console.log('--- NORMAL MATCH FLAG ---') console.log('--- NORMAL MATCH FLAG ---')
this.liveState = NORMAL_RENDER_MATCHED this.liveState = LiveState.NORMAL_RENDER_MATCHED
return match return match
} else if ((livePathMatch || props.alwaysLive) && this.routeDom) { } else if ((livePathMatch || props.alwaysLive) && this.routeDom) {
// backup router when from normal match render to hide render // backup router when from normal match render to hide render
...@@ -200,14 +203,14 @@ class LiveRoute extends React.Component<IProps, any> { ...@@ -200,14 +203,14 @@ class LiveRoute extends React.Component<IProps, any> {
} }
// hide render // hide render
console.log('--- HIDE FLAG ---') console.log('--- HIDE FLAG ---')
this.liveState = HIDE_RENDER this.liveState = LiveState.HIDE_RENDER
this.saveScrollPosition() this.saveScrollPosition()
this.hideRoute() this.hideRoute()
return prevMatch return prevMatch
} else { } else {
// normal unmatched unmount // normal unmatched unmount
console.log('--- NORMAL UNMATCH FLAG ---') console.log('--- NORMAL UNMATCH FLAG ---')
this.liveState = NORMAL_RENDER_UNMATCHED this.liveState = LiveState.NORMAL_RENDER_UNMATCHED
this.clearScroll() this.clearScroll()
this.clearDomData() this.clearDomData()
} }
...@@ -320,13 +323,13 @@ class LiveRoute extends React.Component<IProps, any> { ...@@ -320,13 +323,13 @@ class LiveRoute extends React.Component<IProps, any> {
if ((livePath || alwaysLive) && (component || render)) { if ((livePath || alwaysLive) && (component || render)) {
console.log('=== RENDER FLAG: ' + this.liveState + ' ===') console.log('=== RENDER FLAG: ' + this.liveState + ' ===')
if ( if (
this.liveState === NORMAL_RENDER_MATCHED || this.liveState === LiveState.NORMAL_RENDER_MATCHED ||
this.liveState === NORMAL_RENDER_UNMATCHED || this.liveState === LiveState.NORMAL_RENDER_UNMATCHED ||
this.liveState === NORMAL_RENDER_ON_INIT this.liveState === LiveState.NORMAL_RENDER_ON_INIT
) { ) {
// normal render // normal render
return this.renderRoute(component, render, props, match) return this.renderRoute(component, render, props, match)
} else if (this.liveState === HIDE_RENDER) { } else if (this.liveState === LiveState.HIDE_RENDER) {
// hide render // hide render
const prevRouter = this._latestMatchedRouter const prevRouter = this._latestMatchedRouter
// load properties from prevRouter and fake props of latest normal render // load properties from prevRouter and fake props of latest normal render
......
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