Skip to content

Commit cdd1450

Browse files
committed
feat: persistence
1 parent 0234bcb commit cdd1450

15 files changed

+236
-130
lines changed

.eslintignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ cjs/
22
es/
33
umd/
44
coverage/
5-
examples/*-umd.js
5+
examples/assets/

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ es/
44
umd/
55
coverage/
66

7-
examples/*-umd.js
7+
examples/assets/
88
*.map
99
.eslintcache
1010
package-lock.json

examples/components/Example.js

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,88 @@ const choices = [ReactRouterExample, ReachRouterExample].reduce(
33
{}
44
)
55

6+
function usePersistentState(initializer, key) {
7+
const result = React.useState(
8+
JSON.parse(sessionStorage.getItem(key) || 'null') || initializer
9+
)
10+
11+
React.useEffect(() => {
12+
sessionStorage.setItem(key, JSON.stringify(result[0]))
13+
}, [key, result])
14+
15+
return result
16+
}
17+
618
function Example() {
7-
const [choice, setChoice] = React.useState(Object.keys(choices)[0])
19+
const [choice, setChoice] = usePersistentState(
20+
Object.keys(choices)[0],
21+
'choice'
22+
)
23+
const [maxHistoryLength, setMaxHistoryLength] = usePersistentState(
24+
2,
25+
'maxHistoryLength'
26+
)
27+
const [persist, setPersist] = usePersistentState(false, 'persist')
28+
const [debug, setDebug] = usePersistentState(false, 'debug')
829

930
const Component = choices[choice]
1031

11-
function handleChange(e) {
32+
function handleExampleChange(e) {
1233
window.history.pushState(null, null, '/')
1334
setChoice(e.target.value)
1435
}
1536

1637
return (
1738
<div>
18-
<select value={choice} onChange={handleChange}>
19-
{Object.keys(choices).map(c => (
20-
<option key={c}>{c}</option>
21-
))}
22-
</select>
39+
<fieldset>
40+
<div>
41+
<select value={choice} onChange={handleExampleChange}>
42+
{Object.keys(choices).map(c => (
43+
<option key={c}>{c}</option>
44+
))}
45+
</select>
46+
</div>
47+
<div>
48+
<label>
49+
<span>max history length </span>
50+
<input
51+
type="number"
52+
value={maxHistoryLength}
53+
onChange={e => setMaxHistoryLength(+e.target.value)}
54+
/>
55+
</label>
56+
</div>
57+
<div>
58+
<label>
59+
<span>persist </span>
60+
<input
61+
type="checkbox"
62+
checked={persist}
63+
onChange={() => setPersist(p => !p)}
64+
/>
65+
{persist && <span>open the console</span>}
66+
</label>
67+
</div>
68+
<div>
69+
<label>
70+
<span>debug </span>
71+
<input
72+
type="checkbox"
73+
checked={debug}
74+
onChange={() => setDebug(d => !d)}
75+
/>
76+
{debug && <span>open the console!</span>}
77+
</label>
78+
</div>
79+
</fieldset>
80+
2381
<div style={{ display: 'flex' }}>
2482
<div style={{ flex: 0.5 }}>
25-
<Component />
83+
<Component
84+
maxHistoryLength={maxHistoryLength}
85+
persist={persist}
86+
debug={debug}
87+
/>
2688
</div>
2789
<div style={{ flex: 1, marginLeft: '3rem' }}>
2890
<Source fileName={choice} />

examples/components/ReachRouterExample.js

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,87 +3,93 @@ const ReachRouterExample = (function () {
33
const { Router, Link } = ReachRouter
44

55
const useNavigationState = useReachRouterNavigationState
6-
const { NavigationStateProvider } = useNavigationState
6+
const { NavigationStateProvider, sessionPersister } = useNavigationState
77

8-
return function ReachRouterExample() {
8+
function ReachRouterExample(props) {
99
return (
1010
<Router>
11-
<Root default></Root>
11+
<Root default {...props}></Root>
1212
</Router>
1313
)
1414
}
1515

16-
function Root() {
16+
function Root({ persist, ...props }) {
17+
const persister = persist
18+
? sessionPersister('reach-router-session-persister')
19+
: undefined
20+
1721
return (
18-
<NavigationStateProvider debug>
22+
<NavigationStateProvider persister={persister} {...props}>
1923
<App />
2024
</NavigationStateProvider>
2125
)
2226
}
2327

28+
Root.propTypes = {
29+
persist: PropTypes.bool,
30+
}
31+
32+
return ReachRouterExample
33+
2434
function App() {
2535
return (
2636
<div>
2737
<header>
2838
<ul>
2939
<li>
30-
<Link to="/">Home</Link>
40+
<Link to="/">Simple</Link>
3141
</li>
3242
<li>
33-
<Link to="/about">About</Link>
43+
<Link to="/complex">Complex</Link>
3444
</li>
3545
<li>
36-
<Link to="/help">Help</Link>
46+
<Link to="/no-state">No state</Link>
3747
</li>
3848
</ul>
3949
</header>
4050
<div>
4151
<Router>
42-
<Home path="/" />
43-
<About path="/about" />
44-
<Help path="/help" />
52+
<Simple path="/" />
53+
<Complex path="/complex" />
54+
<NoState path="/no-state" />
4555
</Router>
4656
</div>
4757
</div>
4858
)
4959
}
5060

51-
function Home() {
61+
function Simple() {
5262
const [state, setState] = useNavigationState(1)
5363

5464
return (
5565
<div>
56-
<h2>Home</h2>
66+
<h2>Simple</h2>
5767
<p>{state}</p>
5868
<button onClick={() => setState(s => s + 1)}>increase</button>
5969
</div>
6070
)
6171
}
6272

63-
function About() {
64-
const [state, setState] = useNavigationState(10)
65-
66-
return (
67-
<div>
68-
<h2>About</h2>
69-
<p>{state}</p>
70-
<button onClick={() => setState(s => s + 1)}>increase</button>
71-
</div>
72-
)
73-
}
74-
75-
function Help() {
73+
function Complex() {
7674
const [state1, setState1] = useNavigationState(100, { prefix: 'prefix1' })
7775
const [state2, setState2] = useNavigationState(200, { prefix: 'prefix2' })
7876

7977
return (
8078
<div>
81-
<h2>Help</h2>
79+
<h2>Complex</h2>
8280
<p>State1: {state1}</p>
8381
<p>State2: {state2}</p>
8482
<button onClick={() => setState1(s => s + 1)}>increase 1</button>
8583
<button onClick={() => setState2(s => s + 1)}>increase 2</button>
8684
</div>
8785
)
8886
}
87+
88+
function NoState() {
89+
return (
90+
<div>
91+
<h2>No State</h2>
92+
</div>
93+
)
94+
}
8995
})()

examples/components/ReactRouterExample.js

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,81 +3,87 @@ const ReactRouterExample = (function () {
33
const { BrowserRouter, Link, Route, Switch } = ReactRouterDOM
44

55
const useNavigationState = useReactRouterNavigationState
6-
const { NavigationStateProvider } = useNavigationState
6+
const { NavigationStateProvider, sessionPersister } = useNavigationState
7+
8+
function ReactRouterExample({ persist, ...props }) {
9+
const persister = persist
10+
? sessionPersister('react-router-session-persister')
11+
: undefined
712

8-
return function ReactRouterExample() {
913
return (
1014
<BrowserRouter>
11-
<NavigationStateProvider debug>
15+
<NavigationStateProvider persister={persister} {...props}>
1216
<App />
1317
</NavigationStateProvider>
1418
</BrowserRouter>
1519
)
1620
}
1721

22+
ReactRouterExample.propTypes = {
23+
persist: PropTypes.bool,
24+
}
25+
26+
return ReactRouterExample
27+
1828
function App() {
1929
return (
2030
<div>
2131
<header>
2232
<ul>
2333
<li>
24-
<Link to="/">Home</Link>
34+
<Link to="/">Simple</Link>
2535
</li>
2636
<li>
27-
<Link to="/about">About</Link>
37+
<Link to="/complex">Complex</Link>
2838
</li>
2939
<li>
30-
<Link to="/help">Help</Link>
40+
<Link to="/no-state">No state</Link>
3141
</li>
3242
</ul>
3343
</header>
3444
<div>
3545
<Switch>
36-
<Route path="/" exact component={Home} />
37-
<Route path="/about" component={About} />
38-
<Route path="/help" component={Help} />
46+
<Route path="/" exact component={Simple} />
47+
<Route path="/complex" component={Complex} />
48+
<Route path="/no-state" component={NoState} />
3949
</Switch>
4050
</div>
4151
</div>
4252
)
4353
}
4454

45-
function Home() {
55+
function Simple() {
4656
const [state, setState] = useNavigationState(1)
4757

4858
return (
4959
<div>
50-
<h2>Home</h2>
60+
<h2>Simple</h2>
5161
<p>{state}</p>
5262
<button onClick={() => setState(s => s + 1)}>increase</button>
5363
</div>
5464
)
5565
}
5666

57-
function About() {
58-
const [state, setState] = useNavigationState(10)
59-
60-
return (
61-
<div>
62-
<h2>About</h2>
63-
<p>{state}</p>
64-
<button onClick={() => setState(s => s + 1)}>increase</button>
65-
</div>
66-
)
67-
}
68-
69-
function Help() {
67+
function Complex() {
7068
const [state1, setState1] = useNavigationState(100, { prefix: 'prefix1' })
7169
const [state2, setState2] = useNavigationState(200, { prefix: 'prefix2' })
7270

7371
return (
7472
<div>
75-
<h2>Help</h2>
73+
<h2>Complex</h2>
7674
<p>State1: {state1}</p>
7775
<p>State2: {state2}</p>
7876
<button onClick={() => setState1(s => s + 1)}>increase 1</button>
7977
<button onClick={() => setState2(s => s + 1)}>increase 2</button>
8078
</div>
8179
)
8280
}
81+
82+
function NoState() {
83+
return (
84+
<div>
85+
<h2>No State</h2>
86+
</div>
87+
)
88+
}
8389
})()

examples/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
<script src="https://unpkg.com/@reach/router@1.3.4/umd/reach-router.min.js"></script>
1111
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
1212

13-
<script src="react-router-umd.js"></script>
14-
<script src="reach-router-umd.js"></script>
13+
<script src="assets/react-router-umd.js"></script>
14+
<script src="assets/reach-router-umd.js"></script>
1515
<script type="text/babel" src="components/ReactRouterExample.js"></script>
1616
<script type="text/babel" src="components/ReachRouterExample.js"></script>
1717
<script type="text/babel" src="components/Source.js"></script>

0 commit comments

Comments
 (0)