Skip to content
This repository has been archived by the owner on Feb 14, 2023. It is now read-only.

Commit

Permalink
useDispatch with property behaves analogous to useReducer
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles Stover committed Jun 4, 2019
1 parent c21933c commit 16d6c66
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 22 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,11 @@ state. This allows you to write your reducers similar to React's `useReducer`.
```JavaScript
import React, { useDispatch } from 'reactn'; // <-- reactn

const incrementReducer = (global, dispatch, action) =>
global.count + action.amount;
const incrementReducer = (count, action) =>
count + action.amount;

const decrementReducer = (global, dispatch, action) =>
global.count - action.amount;
const decrementReducer = (count, action) =>
count - action.amount;

const MyComponent = () => {
const increment = useDispatch(incrementReducer, 'count');
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reactn",
"version": "2.1.0",
"version": "2.1.1",
"author": "Charles Stover <[email protected]>",
"description": "React, but with built-in global state management.",
"homepage": "https://github.com/CharlesStover/reactn#readme",
Expand Down
4 changes: 2 additions & 2 deletions src/create-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ export default function _createProvider<
reducer: Reducer<G, R, A>,
): Dispatcher<G, A>;
public static useDispatch<A extends any[] = any[], P extends keyof G = keyof G>(
reducer: PropertyReducer<G, R, A, P>,
reducer: PropertyReducer<G, A, P>,
property: P,
): Dispatcher<G, A>;
public static useDispatch<K extends keyof R = keyof R>(
reducer: K,
): Dispatcher<G, ExtractArguments<R[K]>>;
public static useDispatch<K extends keyof R = keyof R, A extends any[] = any[], P extends keyof G = keyof G>(
reducer?: K | Reducer<G, R, A> | PropertyReducer<G, R, A, P>,
reducer?: K | Reducer<G, R, A> | PropertyReducer<G, A, P>,
property?: P,
): UseDispatch<G, R, K, A> {

Expand Down
8 changes: 4 additions & 4 deletions src/use-dispatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function _useDispatch<
P extends keyof G = keyof G,
>(
overrideGlobalStateManager: GlobalStateManager<G, R> | null,
reducer: PropertyReducer<G, R, A, P>,
reducer: PropertyReducer<G, A, P>,
property: P,
): Dispatcher<G, A>;

Expand Down Expand Up @@ -83,7 +83,7 @@ export default function _useDispatch<
P extends keyof G = keyof G,
>(
overrideGlobalStateManager: GlobalStateManager<G, R> | null,
reducer?: K | Reducer<G, R, A> | PropertyReducer<G, R, A, P>,
reducer?: K | Reducer<G, R, A> | PropertyReducer<G, A, P>,
property?: P,
): UseDispatch<G, R, K, A> {

Expand Down Expand Up @@ -111,11 +111,11 @@ export default function _useDispatch<
if (isPropertyReducer(reducer, property)) {
const newReducer: Reducer<G, R, A, Partial<G>> = (
global: G,
dispatch: Dispatchers<G, R>,
_dispatch: Dispatchers<G, R>,
...args: A
): Partial<G> => {
const newGlobalState: Partial<G> = Object.create(null);
newGlobalState[property] = reducer(global, dispatch, ...args);
newGlobalState[property] = reducer(global[property], ...args);
return newGlobalState;
};
return globalStateManager.createDispatcher(newReducer);
Expand Down
4 changes: 2 additions & 2 deletions src/utils/is-property-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export default function isPropertyReducer<
A extends any[] = any[],
P extends keyof G = keyof G,
>(
_reducer: Reducer<G, R, A> | PropertyReducer<G, R, A, P>,
_reducer: Reducer<G, R, A> | PropertyReducer<G, A, P>,
property?: keyof G,
): _reducer is PropertyReducer<G, R, A, P> {
): _reducer is PropertyReducer<G, A, P> {
return typeof property !== 'undefined';
};
9 changes: 4 additions & 5 deletions tests/use-dispatch/function-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import GlobalStateManager from '../../src/global-state-manager';
import useDispatch from '../../src/use-dispatch';
import REACT_HOOKS_ERROR from '../../src/utils/react-hooks-error';
import Dispatcher from '../../types/dispatcher';
import Dispatchers from '../../types/dispatchers';
import { PropertyReducer } from '../../types/reducer';
import HookTest from '../utils/hook-test';
import { G, INITIAL_STATE } from '../utils/initial';
Expand All @@ -17,18 +16,18 @@ type P = [ ZReducer, keyof G ];

type V = Dispatcher<G, A>;

type ZReducer = PropertyReducer<G, {}, string[], 'z'>;
type ZReducer = PropertyReducer<G, string[], 'z'>;



const ARGS: string[] = [ 'te', 'st' ];

const REDUCER: ZReducer =
(global: G, _dispatch: Dispatchers<G, {}>, ...args: string[]): G['z'] =>
global.z + args.join('');
(z: G['z'], ...args: string[]): G['z'] =>
z + args.join('');

const STATE_CHANGE: Partial<G> = {
z: REDUCER(INITIAL_STATE, {}, ...ARGS),
z: REDUCER(INITIAL_STATE.z, ...ARGS),
};

const NEW_STATE: G = {
Expand Down
17 changes: 15 additions & 2 deletions types/provider.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Callback from './callback';
import Dispatcher, { ExtractArguments } from './dispatcher';
import Dispatchers from './dispatchers';
import NewGlobalState from './new-global-state';
import Reducer, { AdditionalReducers } from './reducer';
import Reducer, { AdditionalReducers, PropertyReducer } from './reducer';
import { GlobalTuple, StateTuple } from './use-global';
import WithGlobal, { Getter, Setter } from './with-global';

Expand All @@ -17,40 +17,53 @@ export default interface ReactNProvider<
G extends {} = State,
R extends {} = Reducers,
> {

addCallback(callback: Callback<G>): BooleanFunction;

addReducer<A extends any[] = any[]>(
name: string,
reducer: Reducer<G, R, A>,
): BooleanFunction;

addReducers(reducers: AdditionalReducers<G, R>): BooleanFunction;
dispatch: Dispatchers<G, R>;

getDispatch(): Dispatchers<G, R>;

getGlobal(): G;
global: G;

removeCallback(callback: Callback<G>): boolean;

reset(): void;

setGlobal(
newGlobalState: NewGlobalState<G>,
callback?: Callback<G>,
): Promise<G>;

useDispatch(): Dispatchers<G, R>;
useDispatch<A extends any[] = any[]>(
reducer: Reducer<G, R, A>,
): Dispatcher<G, A>;
useDispatch<A extends any[] = any[], P extends keyof G = keyof G>(
reducer: Reducer<G, R, A, G[P]>,
reducer: PropertyReducer<G, A, P>,
property: P,
): Dispatcher<G, A>;
useDispatch<K extends keyof R = keyof R>(
reducer: K,
): Dispatcher<G, ExtractArguments<R[K]>>;

useGlobal(): GlobalTuple<G>;
useGlobal<Property extends keyof G>(
property: Property,
): StateTuple<G, Property>;

withGlobal<HP, LP>(
getter?: Getter<G, R, HP, LP>,
setter?: Setter<G, R, HP, LP>,
): WithGlobal<HP, LP>;

new (props: {}, context?: any): React.Component<{}, {}>;

}
3 changes: 1 addition & 2 deletions types/reducer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ export interface AdditionalReducers<

export interface PropertyReducer<
G extends {} = State,
R extends {} = Reducers,
A extends any[] = any[],
P extends keyof G = keyof G,
> extends CallableFunction {
(global: G, dispatch: Dispatchers<G, R>, ...args: A): G[P];
(value: G[P], ...args: A): G[P];
}


Expand Down

0 comments on commit 16d6c66

Please sign in to comment.