Skip to content

Commit 3fe33e1

Browse files
committed
wouldn't it be nice if the URL was like a React bound input?
1 parent e2c6b6a commit 3fe33e1

File tree

1 file changed

+77
-3
lines changed

1 file changed

+77
-3
lines changed

examples/basic/index.js

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,18 @@ import { devTools } from 'redux-devtools';
1313
import { DevTools, DebugPanel, LogMonitor } from 'redux-devtools/lib/react';
1414
import createHistory from 'history/lib/createBrowserHistory';
1515

16-
@connect(state => ({ routerState: state.router }))
16+
@connect(state => ({ rs: state.router }))
1717
class App extends Component {
1818
render() {
19+
const {rs} = this.props;
1920
const links = [
2021
'/',
2122
'/parent?foo=bar',
2223
'/parent/child?bar=baz',
23-
'/parent/child/123?baz=foo'
24+
'/parent/child/123?baz=foo',
25+
'/parent/child/123?oldbaz=bar',
2426
].map(l =>
25-
<p>
27+
<p key={l}>
2628
<Link to={l}>{l}</Link>
2729
</p>
2830
);
@@ -32,6 +34,9 @@ class App extends Component {
3234
<h1>App Container</h1>
3335
{links}
3436
{this.props.children}
37+
<ul>
38+
{Object.keys(rs).map(key=><li key={key}>{key}: {JSON.stringify(rs[key])}</li>)}
39+
</ul>
3540
</div>
3641
);
3742
}
@@ -48,11 +53,26 @@ class Parent extends Component {
4853
}
4954
}
5055

56+
@connect(state => ({ baz: state.app.baz, childId: state.app.childId }))
5157
class Child extends Component {
5258
render() {
59+
const {baz, childId} = this.props;
5360
return (
5461
<div>
5562
<h2>Child</h2>
63+
<p>baz: {baz}{childId && `, childId: ${childId}`}</p>
64+
65+
<p>These buttons do not send router actions, oldbaz gets replaced by baz, the rest is ignored</p>
66+
67+
<p>Note that count is persistent even when going
68+
back: <button onClick={() =>
69+
this.props.dispatch({type: 'clicked'})
70+
}>counter</button></p>
71+
72+
<p>Note that clientId moves to a new
73+
page: <button onClick={() =>
74+
this.props.dispatch({type: 'next'})
75+
}>next child</button></p>
5676
</div>
5777
);
5878
}
@@ -68,6 +88,29 @@ const routes = (
6888
);
6989

7090
const reducer = combineReducers({
91+
app: (state={baz: 'initial', showParent: true, showChild: false, childId: 123, count: 0}, action) => {
92+
switch (action.type) {
93+
case '@@reduxReactRouter/routerDidChange':
94+
// Some arbitrary conversion of url to state
95+
// It would be good to convert url by default to /[prefix]/[main]/[sub]/[subsub]/[restArray]?[queryObj]#[hash]
96+
const q = action.payload.location.query;
97+
const [nil, main, sub, subsub] = action.payload.location.pathname.split(/\/+/);
98+
const showParent = main === 'parent';
99+
const showChild = showParent ? sub === 'child' : state.showChild;
100+
const childId = showChild ? subsub && +subsub : state.showChild;
101+
return {
102+
...state,
103+
baz: q.baz || q.oldbaz || state.baz,
104+
showParent, showChild, childId
105+
};
106+
case 'clicked':
107+
return {...state, count: state.count + 1};
108+
case 'next':
109+
return {...state, childId: state.childId > 0 ? state.childId + 1 : 1};
110+
default:
111+
return state;
112+
}
113+
},
71114
router: routerStateReducer
72115
});
73116

@@ -79,6 +122,37 @@ const store = compose(
79122
devTools()
80123
)(createStore)(reducer);
81124

125+
// this is the mirror image of the reducer above, there should be some helpers
126+
// maybe a model describing what each section of the url is named and which parameters
127+
// are exportable and/or importable
128+
// then an url compressor could be used without the app caring
129+
store.subscribe(() => {
130+
const {app} = store.getState();
131+
let url;
132+
if (app.showParent) {
133+
if (app.showChild) {
134+
if (app.childId >= 0) {
135+
url = '/parent/child/' + app.childId;
136+
} else {
137+
url = '/parent/child';
138+
}
139+
} else {
140+
url = '/parent';
141+
}
142+
} else {
143+
url = '/';
144+
}
145+
const query = `?baz=${app.baz}&count=${app.count}`;
146+
147+
if (window.location.pathname !== url) {
148+
console.log('pushing url', window.location.pathname, url, window.location.search, query);
149+
window.history.pushState({}, window.document.title, url + query);
150+
} else if (window.location.search !== query) {
151+
console.log('replacing url', window.location.pathname, url, window.location.search, query);
152+
window.history.replaceState({}, window.document.title, url + query);
153+
}
154+
});
155+
82156
class Root extends Component {
83157
render() {
84158
return (

0 commit comments

Comments
 (0)