Skip to content

Commit

Permalink
feat(269): options re-evaluation
Browse files Browse the repository at this point in the history
Fixes #269

Options are now re-evaluated when they change, which can be used to change the behavior

of the component where the hook is used based on internal component state.

For example, the `manual` option could be initially true and then set to false based on

the value of a state property, causing the request to fire when this happens.

Similarly, the `useCache` option could be set to true (its default value) then to false

based on a condition, forcing the next request to skip the cache.

Check out [this example](https://codesandbox.io/s/axios-hooks-options-change-v23tl)
and the docs for additional information.
  • Loading branch information
simoneb committed Jul 4, 2020
1 parent f2827d7 commit 9218707
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 9 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function App() {
- [Pagination](https://codesandbox.io/s/axios-hooks-pagination-1wk3u)
- [Infinite scrolling](https://codesandbox.io/s/axios-hooks-infinite-scrolling-42nw6)
- [Request chaining](https://codesandbox.io/s/axios-hooks-request-chaining-wn12l)
- [Options change detection](https://codesandbox.io/s/axios-hooks-options-change-v23tl)
- [react-native](https://snack.expo.io/@simoneb/axios-hooks-react-native)
- [With react-sortable-hoc](https://codesandbox.io/s/axios-hooks-react-sortable-hoc-eo3oy)
- [With react-router](https://codesandbox.io/s/axios-hooks-react-router-26iwm)
Expand Down
20 changes: 12 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,17 @@ export function makeUseAxios(configurationOptions) {
}

function useAxios(config, options) {
config = configToObject(config)

const stringifiedConfig = JSON.stringify(config)
config = React.useMemo(
() => configToObject(config),
// eslint-disable-next-line react-hooks/exhaustive-deps
[JSON.stringify(config)]
)

options = { manual: false, useCache: true, ...options }
options = React.useMemo(
() => ({ manual: false, useCache: true, ...options }),
// eslint-disable-next-line react-hooks/exhaustive-deps
[JSON.stringify(options)]
)

const cancelSourceRef = React.useRef()

Expand Down Expand Up @@ -228,8 +234,7 @@ export function makeUseAxios(configurationOptions) {
}

return cancelOutstandingRequest
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [stringifiedConfig])
}, [config, options, withCancelToken, cancelOutstandingRequest])

const refetch = React.useCallback(
(configOverride, options) => {
Expand All @@ -244,8 +249,7 @@ export function makeUseAxios(configurationOptions) {
dispatch
)
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[stringifiedConfig]
[config, withCancelToken]
)

return [state, refetch]
Expand Down
64 changes: 63 additions & 1 deletion test/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ function standardTests(
})
})

describe('manual requests', () => {
describe('manual option', () => {
it('should set loading to false on initial render', async () => {
const { result } = setup('', { manual: true })

Expand Down Expand Up @@ -834,6 +834,68 @@ function standardTests(
})
})

describe('option change detection', () => {
it('manual:false to manual:true with cache disabled should execute first request only', async () => {
axios.mockResolvedValue({ data: 'whatever' })

const { waitForNextUpdate, rerender } = setup('', {
manual: false,
useCache: false
})

await waitForNextUpdate()

rerender({ config: '', options: { manual: true } })

expect(axios).toHaveBeenCalledTimes(1)
})

it('manual:true to manual:false with cache disabled should execute second request only', async () => {
axios.mockResolvedValue({ data: 'whatever' })

const { waitForNextUpdate, rerender } = setup('', {
manual: true,
useCache: false
})

rerender({ config: '', options: { manual: false } })

await waitForNextUpdate()

expect(axios).toHaveBeenCalledTimes(1)
})

it('useCache:true to useCache:false should execute both requests', async () => {
axios.mockResolvedValue({ data: 'whatever' })

const { waitForNextUpdate, rerender } = setup('', {
useCache: true
})

await waitForNextUpdate()

rerender({ config: '', options: { useCache: false } })

await waitForNextUpdate()

expect(axios).toHaveBeenCalledTimes(2)
})

it('useCache:false to useCache:true should execute first request only', async () => {
axios.mockResolvedValue({ data: 'whatever' })

const { waitForNextUpdate, rerender } = setup('', {
useCache: false
})

await waitForNextUpdate()

rerender({ config: '', options: { useCache: true } })

expect(axios).toHaveBeenCalledTimes(1)
})
})

describe('configure', () => {
afterEach(() => resetConfigure())

Expand Down

0 comments on commit 9218707

Please sign in to comment.