Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Matchina
GitHub

Stopwatch with React State and Effects

This example demonstrates a React-first implementation using a declarative state machine:

  • Uses React’s native state management and effects
  • Encapsulates all state machine logic in a custom hook
  • Simple, idiomatic React code with clear patterns

TheuseStopwatch hook relies on React for both its state management and effects, making it familiar to React developers.

import{defineStates,createMachine,assignEventApi}from"matchina";
import{useMachine}from"matchina/react";
import{useState,useMemo,useEffect}from"react";
import{tickEffect}from"../lib/tick-effect";
exportfunctionuseStopwatch(){
const[elapsed,setElapsed]=useState(0);
consteffects=useMemo(
()=> ({
run:()=>{
letlastTick=Date.now();
returntickEffect(()=>{
constnow=Date.now();
setElapsed(stopwatch.elapsed+now-lastTick);
lastTick=now;
});
},
clear:()=>{
setElapsed(0);
},
}),
[]
);
// Define the state machine
conststopwatch=useMemo(()=>{
// Define states using defineStates
conststates=defineStates({
Stopped:{},
Ticking:{},
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:elapsed,
setElapsed:setElapsed,
});
}, []);
stopwatch.elapsed=elapsed;
useMachine(stopwatch);
useEffect(()=>{
// if (stopwatch.changeProperty.type === "clear") {
// effects.clear();
// }
returnstopwatch.getState().match(
{
Ticking:effects.run,
Stopped:()=>effects.clear,
},
false
);
}, [stopwatch.getState()]);
returnstopwatch;
}

[8]ページ先頭

©2009-2025 Movatter.jp