-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
57d2546
commit 7554b9a
Showing
5 changed files
with
192 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# `useMethods` | ||
|
||
React hook that simplifies the `useReducer` implementation. | ||
|
||
## Usage | ||
|
||
```jsx | ||
import { useMethods } from 'react-use'; | ||
|
||
const initialState = { | ||
count: 0, | ||
}; | ||
|
||
function createMethods(state) { | ||
return { | ||
reset() { | ||
return initialState; | ||
}, | ||
increment() { | ||
return { ...state, count: state.count + 1 }; | ||
}, | ||
decrement() { | ||
return { ...state, count: state.count - 1 }; | ||
}, | ||
}; | ||
} | ||
|
||
const Demo = () => { | ||
const [state, methods] = useMethods(createMethods, initialState); | ||
|
||
return ( | ||
<> | ||
<p>Count: {state.count}</p> | ||
<button onClick={methods.decrement}>-</button> | ||
<button onClick={methods.increment}>+</button> | ||
</> | ||
); | ||
}; | ||
``` | ||
|
||
## Reference | ||
|
||
```js | ||
const [state, methods] = useMethods(createMethods, initialState); | ||
``` | ||
|
||
- `createMethods` — function that takes current state and return an object containing methods that return updated state. | ||
- `initialState` — initial value of the state. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { storiesOf } from '@storybook/react'; | ||
import * as React from 'react'; | ||
import { useMethods } from '../src'; | ||
import ShowDocs from './util/ShowDocs'; | ||
|
||
const initialState = { | ||
count: 0, | ||
}; | ||
|
||
function createMethods(state) { | ||
return { | ||
reset() { | ||
return initialState; | ||
}, | ||
increment() { | ||
return { ...state, count: state.count + 1 }; | ||
}, | ||
decrement() { | ||
return { ...state, count: state.count - 1 }; | ||
}, | ||
}; | ||
} | ||
|
||
const Demo = () => { | ||
const [state, methods] = useMethods(createMethods, initialState); | ||
|
||
return ( | ||
<> | ||
<p>Count: {state.count}</p> | ||
<button onClick={methods.decrement}>-</button> | ||
<button onClick={methods.increment}>+</button> | ||
</> | ||
); | ||
}; | ||
|
||
storiesOf('State|useMethods', module) | ||
.add('Docs', () => <ShowDocs md={require('../docs/useMethods.md')} />) | ||
.add('Demo', () => <Demo />); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { renderHook, act } from '@testing-library/react-hooks'; | ||
import { useMethods } from '../src'; | ||
|
||
it('should have initialState value as the returned state value', () => { | ||
const initialState = { | ||
count: 10, | ||
}; | ||
|
||
const createMethods = state => ({ | ||
doStuff: () => state, | ||
}); | ||
|
||
const { result } = renderHook(() => useMethods(createMethods, initialState)); | ||
|
||
expect(result.current[0]).toEqual(initialState); | ||
}); | ||
|
||
it('should return wrappedMethods object containing all the methods defined in createMethods', () => { | ||
const initialState = { | ||
count: 10, | ||
}; | ||
|
||
const createMethods = state => ({ | ||
reset() { | ||
return initialState; | ||
}, | ||
increment() { | ||
return { ...state, count: state.count + 1 }; | ||
}, | ||
decrement() { | ||
return { ...state, count: state.count - 1 }; | ||
}, | ||
}); | ||
|
||
const { result } = renderHook(() => useMethods(createMethods, initialState)); | ||
|
||
for (const key of Object.keys(createMethods(initialState))) { | ||
expect(result.current[1][key]).toBeDefined(); | ||
} | ||
}); | ||
|
||
it('should properly update the state based on the createMethods', () => { | ||
const count = 10; | ||
const initialState = { | ||
count, | ||
}; | ||
|
||
const createMethods = state => ({ | ||
reset() { | ||
return initialState; | ||
}, | ||
increment() { | ||
return { ...state, count: state.count + 1 }; | ||
}, | ||
decrement() { | ||
return { ...state, count: state.count - 1 }; | ||
}, | ||
}); | ||
|
||
const { result } = renderHook(() => useMethods(createMethods, initialState)); | ||
|
||
act(() => { | ||
result.current[1].increment(); | ||
}); | ||
expect(result.current[0].count).toBe(count + 1); | ||
|
||
act(() => { | ||
result.current[1].decrement(); | ||
}); | ||
expect(result.current[0].count).toBe(count); | ||
|
||
act(() => { | ||
result.current[1].decrement(); | ||
}); | ||
expect(result.current[0].count).toBe(count - 1); | ||
|
||
act(() => { | ||
result.current[1].reset(); | ||
}); | ||
expect(result.current[0].count).toBe(count); | ||
}); |