From a8b41f5e6510a319d742facfe9ac961d598ab9ce Mon Sep 17 00:00:00 2001 From: Sergei Droganov Date: Wed, 18 Sep 2019 15:47:23 +0300 Subject: [PATCH 1/2] useQueue hook --- README.md | 1 + docs/useQueue.md | 26 +++++++++++++++++++++ src/__stories__/useQueue.story.tsx | 23 +++++++++++++++++++ src/__tests__/useQueue.test.ts | 33 ++++++++++++++++++++++++++ src/index.ts | 1 + src/useQueue.ts | 37 ++++++++++++++++++++++++++++++ 6 files changed, 121 insertions(+) create mode 100644 docs/useQueue.md create mode 100644 src/__stories__/useQueue.story.tsx create mode 100644 src/__tests__/useQueue.test.ts create mode 100644 src/useQueue.ts diff --git a/README.md b/README.md index f54afa21d6..358a7f329c 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,7 @@ - [`useCounter` and `useNumber`](./docs/useCounter.md) — tracks state of a number. [![][img-demo]](https://streamich.github.io/react-use/?path=/story/state-usecounter--demo) - [`useList`](./docs/useList.md) — tracks state of an array. - [`useMap`](./docs/useMap.md) — tracks state of an object. + - [`useQueue`](./docs/useQueue.md) — implements simple queue.
diff --git a/docs/useQueue.md b/docs/useQueue.md new file mode 100644 index 0000000000..6ba34ba238 --- /dev/null +++ b/docs/useQueue.md @@ -0,0 +1,26 @@ +# `useQueue` + +React state hook implements simple queue. + + +## Usage + +```jsx +import { useQueue } from 'react-use'; + +const Demo = () => { + const { add, pop, first, last, size } = useQueue(); + + return ( +
+ + + +
+ ); +}; +``` diff --git a/src/__stories__/useQueue.story.tsx b/src/__stories__/useQueue.story.tsx new file mode 100644 index 0000000000..1c201df6bb --- /dev/null +++ b/src/__stories__/useQueue.story.tsx @@ -0,0 +1,23 @@ +import { storiesOf } from '@storybook/react'; +import * as React from 'react'; +import { useQueue } from '..'; +import ShowDocs from './util/ShowDocs'; + +const Demo = () => { + const { add, pop, first, last, size } = useQueue(); + return ( +
+ + + +
+ ); +}; + +storiesOf('State|useQueue', module) + .add('Docs', () => ) + .add('Demo', () => ); diff --git a/src/__tests__/useQueue.test.ts b/src/__tests__/useQueue.test.ts new file mode 100644 index 0000000000..9b53f73ec7 --- /dev/null +++ b/src/__tests__/useQueue.test.ts @@ -0,0 +1,33 @@ +import { act, renderHook } from '@testing-library/react-hooks'; +import useQueue from '../useQueue'; + +const setUp = (initialQueue?: any[]) => renderHook(() => useQueue(initialQueue)); + +it('takes initial state', () => { + const { result } = setUp([1, 2, 3]); + const { first, last, size } = result.current; + expect(first).toEqual(1); + expect(last).toEqual(3); + expect(size).toEqual(3); +}); + +it('appends new member', () => { + const { result } = setUp([1, 2]); + act(() => { + result.current.add(3); + }); + const { first, last, size } = result.current; + expect(first).toEqual(1); + expect(last).toEqual(3); + expect(size).toEqual(3); +}); + +it('pops oldest member', () => { + const { result } = setUp([1, 2]); + act(() => { + result.current.pop(); + }); + const { first, size } = result.current; + expect(first).toEqual(2); + expect(size).toEqual(1); +}); diff --git a/src/index.ts b/src/index.ts index b3514a7179..cc1fd945cd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -57,6 +57,7 @@ export { default as usePermission } from './usePermission'; export { default as usePrevious } from './usePrevious'; export { default as usePreviousDistinct } from './usePreviousDistinct'; export { default as usePromise } from './usePromise'; +export { default as useQueue } from './useQueue'; export { default as useRaf } from './useRaf'; export { default as useRafLoop } from './useRafLoop'; /** diff --git a/src/useQueue.ts b/src/useQueue.ts new file mode 100644 index 0000000000..795e2735d9 --- /dev/null +++ b/src/useQueue.ts @@ -0,0 +1,37 @@ +import { useState } from 'react'; + +export interface QueueMethods { + add: (item: T) => void; + pop: () => T; + first: T; + last: T; + size: number; +} + +const useQueue = (initialValue: T[] = []): QueueMethods => { + const [state, set] = useState(initialValue); + return { + add: value => { + set(queue => [...queue, value]); + }, + pop: () => { + let result; + set(([first, ...rest]) => { + result = first; + return rest; + }); + return result; + }, + get first() { + return state[0]; + }, + get last() { + return state[state.length - 1]; + }, + get size() { + return state.length; + }, + }; +}; + +export default useQueue; From 15e9bd2bd5e8877fe84561774622aebe43d32af5 Mon Sep 17 00:00:00 2001 From: Sergei Droganov Date: Sun, 22 Sep 2019 15:10:27 +0300 Subject: [PATCH 2/2] rename pop ro remove --- docs/useQueue.md | 6 +++--- src/__stories__/useQueue.story.tsx | 4 ++-- src/__tests__/useQueue.test.ts | 2 +- src/useQueue.ts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/useQueue.md b/docs/useQueue.md index 6ba34ba238..ab05d2f78d 100644 --- a/docs/useQueue.md +++ b/docs/useQueue.md @@ -1,6 +1,6 @@ # `useQueue` -React state hook implements simple queue. +React state hook implements simple FIFO queue. ## Usage @@ -9,7 +9,7 @@ React state hook implements simple queue. import { useQueue } from 'react-use'; const Demo = () => { - const { add, pop, first, last, size } = useQueue(); + const { add, remove, first, last, size } = useQueue(); return (
@@ -19,7 +19,7 @@ const Demo = () => {
  • size: {size}
  • - +
    ); }; diff --git a/src/__stories__/useQueue.story.tsx b/src/__stories__/useQueue.story.tsx index 1c201df6bb..ecb7ab43c8 100644 --- a/src/__stories__/useQueue.story.tsx +++ b/src/__stories__/useQueue.story.tsx @@ -4,7 +4,7 @@ import { useQueue } from '..'; import ShowDocs from './util/ShowDocs'; const Demo = () => { - const { add, pop, first, last, size } = useQueue(); + const { add, remove, first, last, size } = useQueue(); return (
      @@ -13,7 +13,7 @@ const Demo = () => {
    • size: {size}
    - +
    ); }; diff --git a/src/__tests__/useQueue.test.ts b/src/__tests__/useQueue.test.ts index 9b53f73ec7..4a155ff3b2 100644 --- a/src/__tests__/useQueue.test.ts +++ b/src/__tests__/useQueue.test.ts @@ -25,7 +25,7 @@ it('appends new member', () => { it('pops oldest member', () => { const { result } = setUp([1, 2]); act(() => { - result.current.pop(); + result.current.remove(); }); const { first, size } = result.current; expect(first).toEqual(2); diff --git a/src/useQueue.ts b/src/useQueue.ts index 795e2735d9..97a8372dce 100644 --- a/src/useQueue.ts +++ b/src/useQueue.ts @@ -2,7 +2,7 @@ import { useState } from 'react'; export interface QueueMethods { add: (item: T) => void; - pop: () => T; + remove: () => T; first: T; last: T; size: number; @@ -14,7 +14,7 @@ const useQueue = (initialValue: T[] = []): QueueMethods => { add: value => { set(queue => [...queue, value]); }, - pop: () => { + remove: () => { let result; set(([first, ...rest]) => { result = first;