-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rename and repurpose some hooks in
@xstate/react
(#4006)
* useInterpret -> useActorRef * Replace useActor usage with useSelector * One more * useMachine -> useActor * Remove useSpawn * Add changeset * supress some TS errors * remove unused things * remove unused types * remove duplicated things * remove redundant file * remove useActor from the context * move tests around * fixed types * add changeset * Update warnings/errors * fix tests --------- Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
- Loading branch information
1 parent
d0ba42c
commit 42df9a5
Showing
19 changed files
with
1,425 additions
and
1,730 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
--- | ||
'@xstate/react': major | ||
--- | ||
|
||
`useActorRef` is introduced, which returns an `ActorRef` from actor logic: | ||
|
||
```ts | ||
const actorRef = useActorRef(machine, { ... }); | ||
const anotherActorRef = useActorRef(fromPromise(...)); | ||
``` | ||
|
||
~~`useMachine`~~ is deprecated in favor of `useActor`, which works with machines and any other kind of logic | ||
|
||
```diff | ||
-const [state, send] = useMachine(machine); | ||
+const [state, send] = useActor(machine); | ||
const [state, send] = useActor(fromTransition(...)); | ||
``` | ||
|
||
~~`useSpawn`~~ is removed in favor of `useActorRef` | ||
|
||
````diff | ||
-const actorRef = useSpawn(machine); | ||
+const actorRef = useActorRef(machine); | ||
|
||
The previous use of `useActor(actorRef)` is now replaced with just using the `actorRef` directly, and with `useSelector`: | ||
|
||
```diff | ||
-const [state, send] = useActor(actorRef); | ||
+const state = useSelector(actorRef, s => s); | ||
// actorRef.send(...) | ||
```` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@xstate/react': patch | ||
--- | ||
|
||
`useActor` has been removed from the created actor context, you should be able to replace its usage with `MyCtx.useSelector` and `MyCtx.useActorRef`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
export { useMachine } from './useMachine.ts'; | ||
export { useActor } from './useActor.ts'; | ||
export { useInterpret } from './useInterpret.ts'; | ||
export { useActorRef } from './useActorRef.ts'; | ||
export { useSelector } from './useSelector.ts'; | ||
export { useSpawn } from './useSpawn.ts'; | ||
export { shallowEqual } from './shallowEqual.ts'; | ||
export { createActorContext } from './createActorContext.ts'; | ||
|
||
// deprecated | ||
export { useMachine } from './useMachine.ts'; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { useEffect, useState } from 'react'; | ||
import { | ||
AnyActorBehavior, | ||
AnyInterpreter, | ||
AnyStateMachine, | ||
AreAllImplementationsAssumedToBeProvided, | ||
InternalMachineImplementations, | ||
interpret, | ||
ActorRefFrom, | ||
InterpreterOptions, | ||
InterpreterStatus, | ||
Observer, | ||
StateFrom, | ||
toObserver, | ||
SnapshotFrom | ||
} from 'xstate'; | ||
import useConstant from './useConstant.ts'; | ||
import useIsomorphicLayoutEffect from 'use-isomorphic-layout-effect'; | ||
|
||
export function useIdleInterpreter( | ||
machine: AnyActorBehavior, | ||
options: Partial<InterpreterOptions<AnyActorBehavior>> | ||
): AnyInterpreter { | ||
if (process.env.NODE_ENV !== 'production') { | ||
const [initialMachine] = useState(machine); | ||
|
||
if (machine.config !== initialMachine.config) { | ||
console.warn( | ||
`Actor logic has changed between renders. This is not supported and may lead to invalid snapshots.` | ||
); | ||
} | ||
} | ||
|
||
const actorRef = useConstant(() => { | ||
return interpret(machine as AnyStateMachine, options); | ||
}); | ||
|
||
// TODO: consider using `useAsapEffect` that would do this in `useInsertionEffect` is that's available | ||
useIsomorphicLayoutEffect(() => { | ||
(actorRef.behavior as AnyStateMachine).options = ( | ||
machine as AnyStateMachine | ||
).options; | ||
}); | ||
|
||
return actorRef as any; | ||
} | ||
|
||
type RestParams<TBehavior extends AnyActorBehavior> = | ||
TBehavior extends AnyStateMachine | ||
? AreAllImplementationsAssumedToBeProvided< | ||
TBehavior['__TResolvedTypesMeta'] | ||
> extends false | ||
? [ | ||
options: InterpreterOptions<TBehavior> & | ||
InternalMachineImplementations< | ||
TBehavior['__TContext'], | ||
TBehavior['__TEvent'], | ||
TBehavior['__TResolvedTypesMeta'], | ||
true | ||
>, | ||
observerOrListener?: | ||
| Observer<StateFrom<TBehavior>> | ||
| ((value: StateFrom<TBehavior>) => void) | ||
] | ||
: [ | ||
options?: InterpreterOptions<TBehavior> & | ||
InternalMachineImplementations< | ||
TBehavior['__TContext'], | ||
TBehavior['__TEvent'], | ||
TBehavior['__TResolvedTypesMeta'] | ||
>, | ||
observerOrListener?: | ||
| Observer<StateFrom<TBehavior>> | ||
| ((value: StateFrom<TBehavior>) => void) | ||
] | ||
: [ | ||
options?: InterpreterOptions<TBehavior>, | ||
observerOrListener?: | ||
| Observer<SnapshotFrom<TBehavior>> | ||
| ((value: SnapshotFrom<TBehavior>) => void) | ||
]; | ||
|
||
export function useActorRef<TBehavior extends AnyActorBehavior>( | ||
machine: TBehavior, | ||
...[options = {}, observerOrListener]: RestParams<TBehavior> | ||
): ActorRefFrom<TBehavior> { | ||
const service = useIdleInterpreter(machine, options); | ||
|
||
useEffect(() => { | ||
if (!observerOrListener) { | ||
return; | ||
} | ||
let sub = service.subscribe(toObserver(observerOrListener)); | ||
return () => { | ||
sub.unsubscribe(); | ||
}; | ||
}, [observerOrListener]); | ||
|
||
useEffect(() => { | ||
service.start(); | ||
|
||
return () => { | ||
service.stop(); | ||
service.status = InterpreterStatus.NotStarted; | ||
(service as any)._initState(); | ||
}; | ||
}, []); | ||
|
||
return service as any; | ||
} |
Oops, something went wrong.