@xstate/react
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -1,3 +0,2 @@ | ||
import { EventObject, StateMachine, State } from 'xstate'; | ||
import { Interpreter } from 'xstate/lib/interpreter'; | ||
import { EventObject, StateMachine, State, Interpreter } from 'xstate'; | ||
interface InterpreterOptions { | ||
@@ -24,3 +23,4 @@ /** | ||
} | ||
export declare function useMachine<TContext, TEvent extends EventObject>(machine: StateMachine<TContext, any, TEvent>, options?: Partial<InterpreterOptions>): [State<TContext, TEvent>, Interpreter<TContext, any, TEvent>['send']]; | ||
export declare function useMachine<TContext, TEvent extends EventObject>(machine: StateMachine<TContext, any, TEvent>, options?: Partial<InterpreterOptions>): [State<TContext, TEvent>, Interpreter<TContext, any, TEvent>['send'], Interpreter<TContext, any, TEvent>]; | ||
export declare function useService<TContext, TEvent extends EventObject>(service: Interpreter<TContext, any, TEvent>): [State<TContext, TEvent>, Interpreter<TContext, any, TEvent>['send'], Interpreter<TContext, any, TEvent>]; | ||
export {}; |
@@ -45,4 +45,20 @@ "use strict"; | ||
}, []); | ||
return [current, service.send]; | ||
return [current, service.send, service]; | ||
} | ||
exports.useMachine = useMachine; | ||
function useService(service) { | ||
var _a = __read(react_1.useState(service.state), 2), current = _a[0], setCurrent = _a[1]; | ||
react_1.useEffect(function () { | ||
var listener = function (state) { | ||
if (state.changed) { | ||
setCurrent(state); | ||
} | ||
}; | ||
service.onTransition(listener); | ||
return function () { | ||
service.off(listener); | ||
}; | ||
}, []); | ||
return [current, service.send, service]; | ||
} | ||
exports.useService = useService; |
{ | ||
"name": "@xstate/react", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "XState tools for React", | ||
@@ -32,3 +32,3 @@ "keywords": [ | ||
"test": "jest", | ||
"prepublish": "tsc" | ||
"prepublish": "tsc && npm run test" | ||
}, | ||
@@ -42,3 +42,3 @@ "bugs": { | ||
"dependencies": { | ||
"xstate": "^4.4.0" | ||
"xstate": "^4.5.0" | ||
}, | ||
@@ -45,0 +45,0 @@ "devDependencies": { |
@@ -1,2 +0,2 @@ | ||
# XState React Tools | ||
# @xstate/react | ||
@@ -54,7 +54,21 @@ ## Quick Start | ||
**Returns** a tuple of `[current, send]`: | ||
**Returns** a tuple of `[current, send, service]`: | ||
- `current` - Represents the current state of the machine as an XState `State` object. | ||
- `send` - A function that sends events to the running service. | ||
- `service` - The created service. | ||
### `useService(service)` | ||
A [React hook](https://reactjs.org/hooks) that subscribes to state changes from an existing [service](TODO). | ||
**Arguments** | ||
- `service` - An [XState service](https://xstate.js.org/docs/guides/communication.html). | ||
**Returns** a tuple of `[current, send]`: | ||
- `current` - Represents the current state of the service as an XState `State` object. | ||
- `send` - A function that sends events to the running service. | ||
## Configuring Machines | ||
@@ -64,2 +78,6 @@ | ||
::: tip | ||
The [`useMemo` hook](TODO) is an important performance optimization when creating a machine with custom config inside of a React component. It ensures that the machine isn't recreated every time the component rerenders. | ||
::: | ||
Example: the `'fetchData'` service and `'notifyChanged'` action are both configurable: | ||
@@ -97,16 +115,20 @@ | ||
const Fetcher = ({ onResolve }) => { | ||
const [current, send] = useMachine( | ||
fetchMachine.withContext({ | ||
actions: { | ||
notifyResolve: ctx => { | ||
onResolve(ctx.data); | ||
const customFetchMachine = useMemo( | ||
() => | ||
fetchMachine.withContext({ | ||
actions: { | ||
notifyResolve: ctx => { | ||
onResolve(ctx.data); | ||
} | ||
}, | ||
services: { | ||
fetchData: (ctx, e) => | ||
fetch(`some/api/${e.query}`).then(res => res.json()) | ||
} | ||
}, | ||
services: { | ||
fetchData: (ctx, e) => | ||
fetch(`some/api/${e.query}`).then(res => res.json()) | ||
} | ||
}) | ||
}), | ||
[] // Machine should never change | ||
); | ||
const [current, send] = useMachine(customFetchMachine); | ||
switch (current.state) { | ||
@@ -145,1 +167,21 @@ case 'idle': | ||
``` | ||
A ternary statement can also be considered, especially within rendered JSX: | ||
```jsx | ||
const Loader = () => { | ||
const [current, send] = useMachine(/* ... */); | ||
return ( | ||
<div> | ||
{current.matches('idle') ? ( | ||
<Loader.Idle /> | ||
) : current.matches({ loading: 'user' }) ? ( | ||
<Loader.LoadingUser /> | ||
) : current.matches({ loading: 'frends' }) ? ( | ||
<Loader.LoadingFriends /> | ||
) : null} | ||
</div> | ||
); | ||
}; | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
9462
88
184
Updatedxstate@^4.5.0