Skip to content

Commit b060899

Browse files
kanellocpvinis
andauthored
feat: add useRefresh hook (#320)
Co-authored-by: Pavlos Vinieratos <[email protected]>
1 parent d13ac21 commit b060899

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ yarn add @react-native-community/hooks
3030
- [useInteractionManager](https://github.com/react-native-community/hooks#useinteractionmanager)
3131
- [useDeviceOrientation](https://github.com/react-native-community/hooks#usedeviceorientation)
3232
- [useLayout](https://github.com/react-native-community/hooks#uselayout)
33+
- [useRefresh](https://github.com/react-native-community/hooks#useRefresh)
3334

3435
### `useAccessibilityInfo`
3536

@@ -131,6 +132,27 @@ console.log('layout: ', layout)
131132
<View onLayout={onLayout} style={{width: 200, height: 200, marginTop: 30}} />
132133
```
133134

135+
### `useRefresh`
136+
137+
```js
138+
import { useRefresh } from '@react-native-community/hooks'
139+
140+
const fetch = () => {
141+
return new Promise((resolve) => setTimeout(resolve, 500))
142+
}
143+
144+
const { isRefreshing, onRefresh } = useRefresh(fetch);
145+
146+
<ScrollView
147+
refreshControl= {
148+
<RefreshControl
149+
refreshing={isRefreshing}
150+
onRefresh={onRefresh}
151+
/>
152+
}
153+
/>
154+
```
155+
134156
[version-badge]: https://img.shields.io/npm/v/@react-native-community/hooks.svg?style=flat-square
135157
[package]: https://www.npmjs.com/package/@react-native-community/hooks
136158

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {useInteractionManager} from './useInteractionManager'
66
import {useDeviceOrientation} from './useDeviceOrientation'
77
import {useLayout} from './useLayout'
88
import {useImageDimensions} from './useImageDimensions'
9+
import {useRefresh} from './useRefresh'
910

1011
export {
1112
useAccessibilityInfo,
@@ -16,4 +17,5 @@ export {
1617
useInteractionManager,
1718
useKeyboard,
1819
useLayout,
20+
useRefresh,
1921
}

src/useRefresh.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {act, renderHook} from '@testing-library/react-hooks'
2+
import {useRefresh} from './useRefresh'
3+
4+
const DELAY_IN_MS = 300
5+
jest.useFakeTimers()
6+
describe('useRefresh', () => {
7+
it('should invoke refresh and return correct refreshing state', () => {
8+
const wait = () => {
9+
return new Promise((resolve) => setTimeout(resolve, DELAY_IN_MS))
10+
}
11+
12+
const {result} = renderHook(() => useRefresh(wait))
13+
14+
const spy = jest.spyOn(result.current, 'onRefresh')
15+
act(() => {
16+
result.current.onRefresh()
17+
})
18+
19+
expect(result.current.isRefreshing).toBe(true)
20+
expect(spy).toHaveBeenCalledTimes(1)
21+
act(() => {
22+
jest.advanceTimersByTime(DELAY_IN_MS)
23+
})
24+
25+
expect(result.current.isRefreshing).toBe(false)
26+
})
27+
})

src/useRefresh.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {useState} from 'react'
2+
3+
export function useRefresh(refresh: () => Promise<unknown>) {
4+
const [isRefreshing, setIsRefreshing] = useState<boolean>(false)
5+
6+
async function onRefresh() {
7+
setIsRefreshing(true)
8+
9+
try {
10+
await refresh()
11+
} finally {
12+
setIsRefreshing(false)
13+
}
14+
}
15+
16+
return {isRefreshing, onRefresh}
17+
}

0 commit comments

Comments
 (0)