Skip to content

Commit

Permalink
Adds useStore hook
Browse files Browse the repository at this point in the history
  • Loading branch information
ctrlplusb committed Oct 1, 2019
1 parent 08ab8d9 commit e128e1e
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 11 deletions.
20 changes: 19 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,23 @@ export function useStoreActions<StoreActions extends Actions<any>, Result>(
mapActions: (actions: StoreActions) => Result,
): Result;

/**
* A react hook that returns the store instance.
*
* @example
*
* import { useStore } from 'easy-peasy';
*
* function MyComponent() {
* const store = useStore();
* return <div>{store.getState().foo}</div>;
* }
*/
export function useStore<
StoreModel extends object = {},
StoreConfig extends EasyPeasyConfig<any, any> = any
>(): Store<StoreModel, StoreConfig>;

/**
* A React Hook allowing you to use the store's dispatch within your component.
*
Expand All @@ -695,7 +712,7 @@ export function useStoreDispatch<StoreModel extends object = {}>(): Dispatch<
* A utility function used to create pre-typed hooks.
*
* @example
* const { useStoreActions, useStoreState, useStoreDispatch } = createTypedHooks<StoreModel>();
* const { useStoreActions, useStoreState, useStoreDispatch, useStore } = createTypedHooks<StoreModel>();
*
* useStoreActions(actions => actions.todo.add); // fully typed
*/
Expand All @@ -708,6 +725,7 @@ export function createTypedHooks<StoreModel extends Object = {}>(): {
mapState: (state: State<StoreModel>) => Result,
dependencies?: Array<any>,
) => Result;
useStore: () => Store<StoreModel>;
};

// #endregion
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"@babel/register": "^7.6.2",
"@testing-library/jest-dom": "^4.1.0",
"@testing-library/react": "^9.2.0",
"@testing-library/react-hooks": "^2.0.1",
"@types/react": "^16.9.4",
"@types/react-dom": "^16.9.1",
"@types/react-redux": "^7.1.4",
Expand Down
2 changes: 2 additions & 0 deletions src/__tests__/create-typed-hooks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
useStoreActions,
useStoreDispatch,
useStoreState,
useStore,
} from '../index';

test('exports all hooks', () => {
Expand All @@ -13,4 +14,5 @@ test('exports all hooks', () => {
expect(typedHooks.useStoreActions).toBe(useStoreActions);
expect(typedHooks.useStoreState).toBe(useStoreState);
expect(typedHooks.useStoreDispatch).toBe(useStoreDispatch);
expect(typedHooks.useStore).toBe(useStore);
});
6 changes: 6 additions & 0 deletions src/__tests__/typescript/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
useStoreActions,
useStoreDispatch,
useStoreState,
useStore,
} from 'easy-peasy';

interface Model {
Expand Down Expand Up @@ -41,6 +42,9 @@ let useActionResult = useStoreActions(
);
useActionResult(1);

let store = useStore<Model>();
store.getState().stateString + 'world';

const typedHooks = createTypedHooks<Model>();

useStoreResult = typedHooks.useStoreState(state => state.stateNumber);
Expand All @@ -51,3 +55,5 @@ dispatch = typedHooks.useStoreDispatch();
dispatch({
type: 'FOO',
});
store = typedHooks.useStore();
store.getState().stateString + 'world';
24 changes: 24 additions & 0 deletions src/__tests__/use-store.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { render } from '@testing-library/react';

import { createStore, StoreProvider, useStore } from '../index';

test('returns the store instance', () => {
// arrange
const store = createStore({
foo: 'bar',
});

const Consumer = () => {
const actual = useStore();
expect(actual).toBe(store);
return null;
};

// act
render(
<StoreProvider store={store}>
<Consumer />
</StoreProvider>,
);
});
5 changes: 5 additions & 0 deletions src/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,15 @@ export function createStoreDispatchHook(Context) {

export const useStoreDispatch = createStoreDispatchHook(EasyPeasyContext);

export function useStore() {
return useContext(EasyPeasyContext);
}

export function createTypedHooks() {
return {
useStoreActions,
useStoreDispatch,
useStoreState,
useStore,
};
}
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
useStoreActions,
useStoreDispatch,
useStoreState,
useStore,
} from './hooks';
import createStore from './create-store';
import createContextStore from './create-context-store';
Expand Down Expand Up @@ -43,4 +44,5 @@ export {
useStoreActions,
useStoreDispatch,
useStoreState,
useStore,
};
1 change: 1 addition & 0 deletions website/docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module.exports = {
'api/use-store-actions',
'api/use-store-dispatch',
'api/use-store-state',
'api/use-store',
],
},
{
Expand Down
24 changes: 24 additions & 0 deletions website/docs/docs/api/use-store.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# useStore

A [hook](https://reactjs.org/docs/hooks-intro.html) granting your components access to the [store](/docs/api/store.html) instance.

> This should only be used for advanced or exceptional cases, for e.g. when you would like to dynamically extend the store deep within your component tree.
```javascript
const store = useStore();
```

## Example

```javascript
import { useStore } from 'easy-peasy';

const AddTodo = () => {
const store = useStore();
return (
<div>
{store.getState().sayHello}
</div>
);
};
```
5 changes: 3 additions & 2 deletions website/docs/docs/typescript-api/create-typed-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ Creates typed versions of the hooks so that you don't need to apply typing infor
import { createTypedHooks } from 'easy-peasy';
import { StoreModel } from './model';

const { useStoreActions, useStoreState, useStoreDispatch } = createTypedHooks<StoreModel>();
const { useStoreActions, useStoreState, useStoreDispatch, useStore } = createTypedHooks<StoreModel>();

export default {
useStoreActions,
useStoreState,
useStoreDispatch
useStoreDispatch,
useStore
}
```

Expand Down
32 changes: 24 additions & 8 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -885,20 +885,20 @@
dependencies:
regenerator-runtime "^0.13.2"

"@babel/runtime@^7.5.4", "@babel/runtime@^7.6.0":
version "7.6.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd"
integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==
dependencies:
regenerator-runtime "^0.13.2"

"@babel/runtime@^7.5.5":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
dependencies:
regenerator-runtime "^0.13.2"

"@babel/runtime@^7.6.0":
version "7.6.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.2.tgz#c3d6e41b304ef10dcf13777a33e7694ec4a9a6dd"
integrity sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==
dependencies:
regenerator-runtime "^0.13.2"

"@babel/template@^7.0.0", "@babel/template@^7.1.0", "@babel/template@^7.2.2", "@babel/template@^7.4.0":
version "7.4.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.0.tgz#12474e9c077bae585c5d835a95c0b0b790c25c8b"
Expand Down Expand Up @@ -1265,6 +1265,15 @@
pretty-format "^24.0.0"
redent "^3.0.0"

"@testing-library/react-hooks@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-2.0.1.tgz#1c3ec40882d0830df3078ddae0056fdf7366c81d"
integrity sha512-MLTvWX7/csq/uQzP4WJntGz0QJDq6H4EzjV0VTL5YJE7KBZbaQ9DGT0IbtjuB33L4R4YKZ55rGZQ5eL+WiZtQA==
dependencies:
"@babel/runtime" "^7.5.4"
"@types/react" ">=16.9.0"
"@types/react-test-renderer" ">=16.9.0"

"@testing-library/react@^9.2.0":
version "9.2.0"
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-9.2.0.tgz#143ad2d96b03c3c334e47aaf33cc2c9b7d007123"
Expand Down Expand Up @@ -1407,7 +1416,14 @@
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"

"@types/react@*", "@types/react@16.9.4", "@types/react@^16.9.4":
"@types/react-test-renderer@>=16.9.0":
version "16.9.0"
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-16.9.0.tgz#d60f530ecf4c906721511603cca711b4fa830d41"
integrity sha512-bN5EyjtuTY35xX7N5j0KP1vg5MpUXHpFTX6tGsqkNOthjNvet4VQOYRxFh+NT5cDSJrATmAFK9NLeYZ4mp/o0Q==
dependencies:
"@types/react" "*"

"@types/react@*", "@types/react@16.9.4", "@types/react@>=16.9.0", "@types/react@^16.9.4":
version "16.9.4"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.4.tgz#de8cf5e5e2838659fb78fa93181078469eeb19fc"
integrity sha512-ItGNmJvQ0IvWt8rbk5PLdpdQhvBVxAaXI9hDlx7UMd8Ie1iMIuwMNiKeTfmVN517CdplpyXvA22X4zm4jGGZnw==
Expand Down

0 comments on commit e128e1e

Please sign in to comment.