Skip to content

Commit d73f4c3

Browse files
committed
chore: controlled/uncontrolled cleanup
1 parent 26ba6ab commit d73f4c3

15 files changed

+269
-243
lines changed

examples/.eslintrc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"useTokenPagination": true,
1111
"Output": true,
1212
"Source": true,
13-
"SimpleDeclarative": true,
14-
"SimpleImperative": true,
15-
"InternalState": true
13+
"ControlledDeclarative": true,
14+
"ControlledImperative": true,
15+
"Uncontrolled": true
1616
}
1717
}

examples/components/SimpleDeclarative.js renamed to examples/components/ControlledDeclarative.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
const { useState, useEffect } = React
22

3-
function SimpleDeclarative() {
3+
function ControlledDeclarative() {
44
const [{ pageNumber, pageSize }, setPagination] = useState({
55
pageNumber: 1,
66
pageSize: 3,
77
})
88
const { currentToken, useUpdateToken } = useTokenPagination(pageNumber)
9-
9+
const [loading, setLoading] = useState(false)
1010
const [data, setData] = useState()
1111

1212
useEffect(() => {
1313
async function fetchData() {
14+
setLoading(true)
15+
1416
const params = new URLSearchParams({ pageSize })
1517

1618
if (currentToken) {
@@ -21,6 +23,7 @@ function SimpleDeclarative() {
2123
const data = await res.json()
2224

2325
setData(data)
26+
setLoading(false)
2427
}
2528

2629
fetchData()
@@ -45,9 +48,9 @@ function SimpleDeclarative() {
4548
pageSize={pageSize}
4649
changePageSize={changePageSize}
4750
previousPage={previousPage}
48-
nextPage={nextPage}
51+
nextPage={!loading && nextPage}
4952
/>
5053
)
5154
}
5255

53-
SimpleDeclarative.propTypes = {}
56+
ControlledDeclarative.propTypes = {}

examples/components/SimpleImperative.js renamed to examples/components/ControlledImperative.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
const { useState, useEffect } = React
22

3-
function SimpleImperative() {
3+
function ControlledImperative() {
44
const [{ pageNumber, pageSize }, setPagination] = useState({
55
pageNumber: 1,
66
pageSize: 3,
77
})
88
const { currentToken, updateToken } = useTokenPagination(pageNumber)
9-
9+
const [loading, setLoading] = useState(false)
1010
const [data, setData] = useState()
1111

1212
useEffect(() => {
1313
async function fetchData() {
14+
setLoading(true)
15+
1416
const params = new URLSearchParams({ pageSize })
1517

1618
if (currentToken) {
@@ -23,6 +25,7 @@ function SimpleImperative() {
2325
updateToken(data.nextPage)
2426

2527
setData(data)
28+
setLoading(false)
2629
}
2730

2831
fetchData()
@@ -45,9 +48,9 @@ function SimpleImperative() {
4548
pageSize={pageSize}
4649
changePageSize={changePageSize}
4750
previousPage={previousPage}
48-
nextPage={nextPage}
51+
nextPage={!loading && nextPage}
4952
/>
5053
)
5154
}
5255

53-
SimpleImperative.propTypes = {}
56+
ControlledImperative.propTypes = {}

examples/components/Example.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
const choices = [SimpleDeclarative, SimpleImperative, InternalState].reduce(
2-
(acc, c) => ({ ...acc, [c.name]: c }),
3-
{}
4-
)
1+
const choices = [
2+
ControlledDeclarative,
3+
ControlledImperative,
4+
Uncontrolled,
5+
].reduce((acc, c) => ({ ...acc, [c.name]: c }), {})
56

67
function Example() {
7-
const [choice, setChoice] = React.useState(SimpleDeclarative.name)
8+
const [choice, setChoice] = React.useState(ControlledDeclarative.name)
89

910
const Component = choices[choice]
1011

examples/components/Output.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function Output({
2525
{' '}
2626
{pageNumber}
2727
{' '}
28-
<button disabled={!data?.nextPage} onClick={nextPage}>
28+
<button disabled={!nextPage || !data?.nextPage} onClick={nextPage}>
2929
&gt;&gt;
3030
</button>
3131
</div>
@@ -41,5 +41,5 @@ Output.propTypes = {
4141
pageSize: T.number.isRequired,
4242
changePageSize: T.func.isRequired,
4343
previousPage: T.func.isRequired,
44-
nextPage: T.func.isRequired,
44+
nextPage: T.func,
4545
}

examples/components/InternalState.js renamed to examples/components/Uncontrolled.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const { useState, useEffect } = React
22

3-
function InternalState() {
3+
function Uncontrolled() {
44
const {
55
currentToken,
66
useUpdateToken,
@@ -9,11 +9,13 @@ function InternalState() {
99
pageNumber,
1010
pageSize,
1111
} = useTokenPagination({ defaultPageNumber: 1, defaultPageSize: 5 })
12-
12+
const [loading, setLoading] = useState(false)
1313
const [data, setData] = useState()
1414

1515
useEffect(() => {
1616
async function fetchData() {
17+
setLoading(true)
18+
1719
const params = new URLSearchParams({ pageSize })
1820

1921
if (currentToken) {
@@ -24,6 +26,7 @@ function InternalState() {
2426
const data = await res.json()
2527

2628
setData(data)
29+
setLoading(false)
2730
}
2831

2932
fetchData()
@@ -48,9 +51,9 @@ function InternalState() {
4851
pageSize={pageSize}
4952
changePageSize={handleChangePageSize}
5053
previousPage={previousPage}
51-
nextPage={nextPage}
54+
nextPage={!loading && nextPage}
5255
/>
5356
)
5457
}
5558

56-
InternalState.propTypes = {}
59+
Uncontrolled.propTypes = {}

examples/index.html

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
<script src="umd.js"></script>
1111
<script type="text/babel" src="components/Output.js"></script>
1212
<script type="text/babel" src="components/Source.js"></script>
13-
<script type="text/babel" src="components/SimpleDeclarative.js"></script>
14-
<script type="text/babel" src="components/SimpleImperative.js"></script>
15-
<script type="text/babel" src="components/InternalState.js"></script>
13+
<script
14+
type="text/babel"
15+
src="components/ControlledDeclarative.js"
16+
></script>
17+
<script type="text/babel" src="components/ControlledImperative.js"></script>
18+
<script type="text/babel" src="components/Uncontrolled.js"></script>
1619
<script type="text/babel" src="components/Example.js"></script>
1720
</head>
1821
<body>

examples/server.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ function api(req, res) {
2828
: null,
2929
}
3030

31-
res.end(JSON.stringify(result))
31+
setTimeout(() => {
32+
res.end(JSON.stringify(result))
33+
}, 1000)
3234
}
3335

3436
function static(req, res) {

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@
1313
"src/"
1414
],
1515
"scripts": {
16-
"dev": "npm run build:watch",
1716
"clean": "rimraf cjs es umd",
18-
"prepare": "npm run clean && npm run build",
17+
"prepare": "run-s clean build",
1918
"build": "rollup -c",
2019
"build:watch": "rollup -c -w",
2120
"lint": "eslint .",
2221
"lint:fix": "eslint . --fix",
2322
"release": "dotenv -e .token release-it --",
2423
"toc": "markdown-toc README.md -i",
2524
"test": "jest",
26-
"example": "node examples/server.js"
25+
"examples": "run-p examples:*",
26+
"examples:server": "nodemon examples/server.js",
27+
"examples:client": "npm run build:watch"
2728
},
2829
"keywords": [
2930
"react",
@@ -52,6 +53,8 @@
5253
"jest": "^26.6.3",
5354
"lint-staged": "^10.5.3",
5455
"markdown-toc": "^1.2.0",
56+
"nodemon": "^2.0.6",
57+
"npm-run-all": "^4.1.5",
5558
"prettier": "^2.2.1",
5659
"react": "^17.0.1",
5760
"react-test-renderer": "^17.0.1",

src/controlled.js

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,34 @@
1-
import { useCallback, useState, useMemo } from 'react'
2-
import useUncontrolledTokenPagination from './uncontrolled'
1+
import { useCallback, useEffect, useState, useMemo } from 'react'
32
import { assertNumber } from './utils'
43

5-
const DEFAULTS = {
6-
defaultPageNumber: 1,
7-
resetPageNumberOnPageSizeChange: true,
8-
}
9-
10-
export default function useControlledTokenPagination(options) {
11-
options = { ...DEFAULTS, ...options }
12-
13-
assertNumber('defaultPageNumber', options.defaultPageNumber)
14-
assertNumber('defaultPageSize', options.defaultPageSize)
15-
16-
const [{ pageNumber, pageSize }, setPagination] = useState({
17-
pageNumber: options.defaultPageNumber,
18-
pageSize: options.defaultPageSize,
19-
})
4+
export default function useControlledTokenPagination(pageNumber) {
5+
assertNumber('pageNumber', pageNumber)
206

21-
const change = useCallback(
22-
(property, changer) => {
23-
const pageNumberReset = options.resetPageNumberOnPageSizeChange
24-
? { pageNumber: options.defaultPageNumber }
25-
: {}
7+
const [mapping, setMapping] = useState({})
268

27-
switch (typeof changer) {
28-
case 'function':
29-
return setPagination(p => ({
30-
...p,
31-
...pageNumberReset,
32-
[property]: changer(p[property]),
33-
}))
34-
case 'number':
35-
return setPagination(p => ({
36-
...p,
37-
...pageNumberReset,
38-
[property]: changer,
39-
}))
40-
default:
41-
throw new Error(
42-
`Unsupported value ${changer} of type ${typeof changer} for ${property}`
43-
)
44-
}
9+
const updateToken = useCallback(
10+
nextToken => {
11+
setMapping(m => ({
12+
...m,
13+
[pageNumber + 1]: nextToken,
14+
}))
4515
},
46-
[options.defaultPageNumber, options.resetPageNumberOnPageSizeChange]
16+
[pageNumber]
4717
)
4818

49-
const changePageNumber = useCallback(c => change('pageNumber', c), [change])
50-
const changePageSize = useCallback(c => change('pageSize', c), [change])
51-
52-
const uncontrolled = useUncontrolledTokenPagination(pageNumber)
19+
const useUpdateToken = useCallback(
20+
function useUpdateToken(nextToken) {
21+
useEffect(() => updateToken(nextToken), [nextToken])
22+
},
23+
[updateToken]
24+
)
5325

5426
return useMemo(
5527
() => ({
56-
...uncontrolled,
57-
pageNumber,
58-
pageSize,
59-
changePageNumber,
60-
changePageSize,
28+
currentToken: mapping[pageNumber],
29+
useUpdateToken,
30+
updateToken,
6131
}),
62-
[changePageNumber, changePageSize, pageNumber, pageSize, uncontrolled]
32+
[mapping, pageNumber, updateToken, useUpdateToken]
6333
)
6434
}

0 commit comments

Comments
 (0)