@@ -13,16 +13,18 @@ import { devTools } from 'redux-devtools';
13
13
import { DevTools , DebugPanel , LogMonitor } from 'redux-devtools/lib/react' ;
14
14
import createHistory from 'history/lib/createBrowserHistory' ;
15
15
16
- @connect ( state => ( { routerState : state . router } ) )
16
+ @connect ( state => ( { rs : state . router } ) )
17
17
class App extends Component {
18
18
render ( ) {
19
+ const { rs} = this . props ;
19
20
const links = [
20
21
'/' ,
21
22
'/parent?foo=bar' ,
22
23
'/parent/child?bar=baz' ,
23
- '/parent/child/123?baz=foo'
24
+ '/parent/child/123?baz=foo' ,
25
+ '/parent/child/123?oldbaz=bar' ,
24
26
] . map ( l =>
25
- < p >
27
+ < p key = { l } >
26
28
< Link to = { l } > { l } </ Link >
27
29
</ p >
28
30
) ;
@@ -32,6 +34,9 @@ class App extends Component {
32
34
< h1 > App Container</ h1 >
33
35
{ links }
34
36
{ this . props . children }
37
+ < ul >
38
+ { Object . keys ( rs ) . map ( key => < li key = { key } > { key } : { JSON . stringify ( rs [ key ] ) } </ li > ) }
39
+ </ ul >
35
40
</ div >
36
41
) ;
37
42
}
@@ -48,11 +53,26 @@ class Parent extends Component {
48
53
}
49
54
}
50
55
56
+ @connect ( state => ( { baz : state . app . baz , childId : state . app . childId } ) )
51
57
class Child extends Component {
52
58
render ( ) {
59
+ const { baz, childId} = this . props ;
53
60
return (
54
61
< div >
55
62
< 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 >
56
76
</ div >
57
77
) ;
58
78
}
@@ -68,6 +88,29 @@ const routes = (
68
88
) ;
69
89
70
90
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
+ } ,
71
114
router : routerStateReducer
72
115
} ) ;
73
116
@@ -79,6 +122,37 @@ const store = compose(
79
122
devTools ( )
80
123
) ( createStore ) ( reducer ) ;
81
124
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
+
82
156
class Root extends Component {
83
157
render ( ) {
84
158
return (
0 commit comments