Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Matchina
GitHub

Stopwatch with React State and State Effects

This is the cleanest, shortest version of the stopwatch examples, using specialized utility hooks:

  • UsesuseStateEffects anduseEventTypeEffect for simplified effect management
  • Relies on React for state management like the React-first example
  • Provides a more declarative approach to handling state-specific effects

The key innovation here is using effects tied directly to states and events (likeclear), which creates a more maintainable separation of concerns.

While this approach is elegant, a more idiomatic pattern would fully separate the machine definition from React into separate files, with effects specified as non-function JS values (strings or objects created bydefineEffects).

import{createMachine,defineStates,assignEventApi}from"matchina";
import{useMachine}from"matchina/react";
import{useMemo,useState}from"react";
import{useEventTypeEffect,useStateEffects}from"../lib/matchina-hooks";
import{tickEffect}from"../lib/tick-effect";
exportfunctionuseStopwatch(){
const[elapsed,setElapsed]=useState(0);
consteffects=useMemo(
()=> ({
clear:()=>setElapsed(0),
run:()=>{
letlastTick=Date.now();
returntickEffect(()=>{
constnow=Date.now();
setElapsed(stopwatch.elapsed+now-lastTick);
lastTick=now;
});
},
}),
[]
);
// Define the state machine
conststopwatch=useMemo(()=>{
// Define states using defineStates
conststates=defineStates({
Stopped:{ effects: [effects.clear]},
Ticking:{ effects: [effects.run]},
Suspended:{},
});
// Create the base machine with states, transitions, and initial state
constbaseMachine=createMachine(
states,
{
Stopped:{
start:"Ticking",
},
Ticking:{
stop:"Stopped",
suspend:"Suspended",
clear:"Ticking",
},
Suspended:{
stop:"Stopped",
resume:"Ticking",
clear:"Suspended",
},
},
"Stopped"
);
//Use assignEventApi to enhance the machine with utility methods
returnObject.assign(assignEventApi(baseMachine),{
elapsed,
});
}, []);
useMachine(stopwatch);
useStateEffects(stopwatch.getState());
useEventTypeEffect(stopwatch.getChange(),effects);
stopwatch.elapsed=elapsed;
returnstopwatch;
}

[8]ページ先頭

©2009-2025 Movatter.jp