Skip to content

Commit 3fa3663

Browse files
authored
Merge pull request #2 from react-gx/dev
Version 1.1.0 - Upgrade useAction hook
2 parents d59eff6 + b200839 commit 3fa3663

File tree

11 files changed

+329
-246
lines changed

11 files changed

+329
-246
lines changed

LICENCE renamed to LICENSE

File renamed without changes.

README.md

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# GX - Global State Management for React Applications
22

3+
`React` and `React Native` Library for managing global state.
4+
5+
[![npm version](https://badge.fury.io/js/%40dilane3%2Fgx.svg)](https://badge.fury.io/js/%40dilane3%2Fgx)
6+
[![npm downloads](https://img.shields.io/npm/dm/%40dilane3%2Fgx)](https://www.npmjs.com/package/@dilane3/gx)
7+
[![GitHub license](https://img.shields.io/github/license/react-gx/gx)](https://github.com/react-gx/gx/blob/main/LICENSE)
8+
9+
310
![logo](./assets/logo.png)
411

512
This library aims to provide you an `easy` and `fast` way to set up and manage the global state of your **`react`** application.
@@ -11,13 +18,13 @@ You can use `npm` or `yarn` to install this library into your react application.
1118
### Using npm
1219

1320
```bash
14-
npm install gx
21+
npm install @dilane3/gx
1522
```
1623

1724
### Using yarn
1825

1926
```bash
20-
yarn add gx
27+
yarn add @dilane3/gx
2128
```
2229

2330
## Prerequisites
@@ -40,6 +47,8 @@ function App() {
4047
</StrictMode>
4148
);
4249
}
50+
51+
export default App;
4352
```
4453

4554
**After**
@@ -56,6 +65,8 @@ function App() {
5665
</Fragment>
5766
);
5867
}
68+
69+
export default App;
5970
```
6071

6172
### Disabling strict mode on Next.js
@@ -113,7 +124,7 @@ Here is the result.
113124
Inside the `signals` directory, create a file called `counter.js` for example.
114125

115126
```js
116-
import { createSignal } from 'gx';
127+
import { createSignal } from '@dilane3/gx';
117128

118129
const counterSignal = createSignal({
119130
name: 'counter',
@@ -137,7 +148,7 @@ export default counterSignal;
137148
Inside the `store` directory, create an `index.js` file.
138149

139150
```js
140-
import { createStore } from "gx";
151+
import { createStore } from "@dilane3/gx";
141152
import counterSignal from "../signals/counter";
142153

143154
export default createStore([counterSignal]);
@@ -150,7 +161,7 @@ Inside your `App.js` file, import your store and wrap your application with the
150161
```js
151162
import React from "react";
152163
import store from "./gx/store";
153-
import GXProvider from "gx";
164+
import GXProvider from "@dilane3/gx";
154165

155166
function App() {
156167
return (
@@ -172,7 +183,7 @@ Create a component called `Counter` inside the Counter.js file. Then import two
172183

173184
```js
174185
import React from "react";
175-
import { useSignal, useAction } from "gx";
186+
import { useSignal, useAction } from "@dilane3/gx";
176187

177188
function Counter() {
178189
// State
@@ -192,6 +203,8 @@ function Counter() {
192203
</div>
193204
);
194205
}
206+
207+
export default Counter;
195208
```
196209

197210
Note that the `useSignal` hook takes the name of the signal as a parameter and return the state contained inside that signal.
@@ -261,12 +274,29 @@ const counter = useSignal("counter");
261274

262275
### `useAction`
263276

264-
This hook takes the name of the signal as a parameter and returns an object that contains all the actions of this signal.
277+
This hook takes the name of the signal as a the first parameter and returns an object that contains all the actions of this signal.
265278

266279
```js
267280
const { increment, decrement } = useAction("counter");
268281
```
269282

283+
**`New in version 1.1.0`**
284+
285+
Note that, the `useAction` hook can accept a second parameter which is the list of actions that you want to use. If you don't specify the second parameter, all the actions of the signal will be returned.
286+
287+
There is another thing that you have to know.
288+
If you provide only one action as a second parameter, the hook will return only the action itself and not an object that contains the action.
289+
290+
```js
291+
const increment = useAction("counter", "increment");
292+
```
293+
294+
And if you provide more than one action, the hook will return an object that contains all the actions provided.
295+
296+
```js
297+
const { increment, decrement } = useAction("counter", "increment", "decrement");
298+
```
299+
270300
## License
271301

272302
[MIT](https://choosealicense.com/licenses/mit/)
@@ -282,7 +312,3 @@ const { increment, decrement } = useAction("counter");
282312

283313
Contributions, issues and feature requests are welcome!
284314
See the [Contributing Guide](./CONTRIBUTING.md).
285-
286-
## Keywords
287-
288-
react, state, management, hooks, gx

dist/hooks/useAction.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
declare const useAction: (signalName: string) => {
1+
declare const useAction: (signalName: string, ...actions: string[]) => ((payload: any) => void) | {
22
[key: string]: (payload: any) => void;
33
};
44
export default useAction;

dist/hooks/useAction.js

Lines changed: 33 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/hooks/useAction.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/providers/reducer.js

Lines changed: 4 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/providers/reducer.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
{
2-
"name": "gx",
3-
"version": "1.0.0",
2+
"name": "@dilane3/gx",
3+
"version": "1.1.0",
44
"private": false,
55
"license": "MIT",
66
"main": "dist/index.js",
7+
"author": {
8+
"name": "dilane3",
9+
"email": "[email protected]",
10+
"url": "https://dilane3.com",
11+
"twitter": "https://twitter.com/dilanekombou",
12+
"github": "https://github.com/dilane3"
13+
},
14+
"repository": {
15+
"type": "git",
16+
"url": "https://github.com/react-gx/gx",
17+
"issues": "https://github.com/react-gx/gx/issues"
18+
},
719
"devDependencies": {
820
"@testing-library/jest-dom": "^5.14.1",
921
"@testing-library/react": "^13.0.0",
@@ -15,12 +27,26 @@
1527
"typescript": "^4.4.2"
1628
},
1729
"peerDependencies": {
18-
"react": "^18.2.0"
30+
"react": "^18.0.0"
1931
},
2032
"scripts": {
2133
"build": "tsc",
2234
"test": "react-scripts test"
2335
},
36+
"keywords": [
37+
"react",
38+
"react-gx",
39+
"gx",
40+
"redux",
41+
"zustand",
42+
"mobx",
43+
"management",
44+
"state",
45+
"state-management",
46+
"react-state-management",
47+
"global",
48+
"global-state"
49+
],
2450
"eslintConfig": {
2551
"extends": [
2652
"react-app",

src/hooks/useAction.ts

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,78 @@
1-
import { useContext, useState, useEffect } from 'react';
1+
import { useContext, useState, useEffect } from "react";
22
import GXContext from "../contexts";
3+
import { GXActionType } from "../contexts/types";
34

4-
5-
const useAction = (signalName: string) => {
5+
const useAction = (signalName: string, ...actions: string[]) => {
66
// Get Global Context
77
const { signals, dispatch } = useContext(GXContext);
88

99
// Some handlers
1010

1111
/**
1212
* Get actions of a signal
13-
* @param signalName
14-
* @returns
13+
* @param signalName
14+
* @returns
1515
*/
1616
const handleGetActions = (signalName: string) => {
17-
const signal = signals.find(signal => signal.name === signalName);
17+
const signal = signals.find((signal) => signal.name === signalName);
1818

1919
if (signal) {
20-
return signal.actions;
21-
}
20+
if (!actions || actions.length === 0) return signal.actions;
21+
22+
const filteredActions : GXActionType<any>[] = [];
23+
24+
for (let action of actions) {
25+
const actionName = `${signalName}/${action}`;
26+
27+
const retrievedAction = signal.actions.find((act) => act.type === actionName);
28+
29+
if (retrievedAction) filteredActions.push(retrievedAction);
30+
else throw new Error(`Action ${actionName} not found`);
31+
}
2232

23-
return [];
24-
}
33+
return filteredActions;
34+
} else throw new Error(`Signal ${signalName} not found`);
35+
};
2536

2637
const handleFormatActions = () => {
2738
// Get actions
2839
const nonFormattedActions = handleGetActions(signalName);
2940

41+
// Get number of actions
42+
const numberOfActions = nonFormattedActions.length;
43+
44+
// Check if actions are only one
45+
if (numberOfActions === 1) {
46+
const action = nonFormattedActions[0];
47+
48+
// Return action as a function
49+
return (payload: any) => {
50+
dispatch({
51+
type: action.type,
52+
payload,
53+
});
54+
};
55+
}
56+
57+
// If actions are more than one
58+
3059
// Formatted actions
3160
const formattedActions: { [key: string]: (payload: any) => void } = {};
3261

3362
for (const action of nonFormattedActions) {
3463
// Get action name
35-
const actionName = action.type.split('/')[1];
64+
const actionName = action.type.split("/")[1];
3665

3766
formattedActions[actionName] = (payload: any) => {
3867
dispatch({
3968
type: action.type,
40-
payload
69+
payload,
4170
});
42-
}
71+
};
4372
}
4473

4574
return formattedActions;
46-
}
75+
};
4776

4877
return handleFormatActions();
4978
};

0 commit comments

Comments
 (0)