Skip to content

Commit

Permalink
Provides a stable send method. Closes #12 (#18)
Browse files Browse the repository at this point in the history
* Provides a stable send method

* Fix linter & lint
  • Loading branch information
cassiozen authored May 17, 2021
1 parent 9e40f1a commit 8989095
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 135 deletions.
8 changes: 5 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
plugins: ['react-hooks'],
rules: {
'react-hooks/exhaustive-deps': 'warn',
extends: ['react-app', 'prettier/@typescript-eslint', 'plugin:prettier/recommended'],
settings: {
react: {
version: 'detect',
},
},
};
15 changes: 11 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@size-limit/preset-small-lib": "^4.10.1",
"@testing-library/react-hooks": "^5.1.0",
"@types/react": "^17.0.3",
"eslint-plugin-react-hooks": "^4.1.0",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "^5.1.3",
"react": ">=16.8.0",
"react-test-renderer": "^17.0.1",
Expand Down
25 changes: 18 additions & 7 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,29 @@ function useStateMachineImpl<Context>(context: Context): UseStateMachineWithCont

const reducer = useConstant(() => getReducer<Context, S, T>(config));

const [machine, send] = useReducer(reducer, initialState);
const [machine, dispatch] = useReducer(reducer, initialState);
// The updater function sends an internal event to the reducer to trigger the actual update
const sendUpdater: Dispatch<ContextUpdate<Context>> = updater => send({ type: 'Update', updater });
// The public updater function exposed to the user
const sendNext: Dispatch<T> = next => send({ type: 'Transition', next });
const update: Dispatch<ContextUpdate<Context>> = updater =>
dispatch({
type: 'Update',
updater,
});
// The public dispatch/send function exposed to the user
const send: Dispatch<T> = useConstant(() => next =>
dispatch({
type: 'Transition',
next,
})
);

useEffect(() => {
const exit = config.states[machine.value]?.effect?.(sendNext, sendUpdater);
return typeof exit === 'function' ? () => exit(sendNext, sendUpdater) : undefined;
const exit = config.states[machine.value]?.effect?.(send, update);
return typeof exit === 'function' ? () => exit(send, update) : undefined;
// We are bypassing the linter here because we deliberately want the effects to run on explicit machine state changes.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [machine.value]);

return [machine, sendNext];
return [machine, send];
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default function log(message: string, ...optionalParams: any[]) {
if (process.env.NODE_ENV === 'development') {
const logArguments = ['%cuseStateMachine ' + `%c${message}`, 'color: #888;', 'color: default;', ...optionalParams];
const logArguments = [`%cuseStateMachine %c${message}`, 'color: #888;', 'color: default;', ...optionalParams];

// Console.log clearly accepts parameters other than string, but TypeScript is complaining, so...
// @ts-ignore
Expand Down
Loading

0 comments on commit 8989095

Please sign in to comment.