# 与 Stencil 一起使用
Stencil (opens new window) web components work very well with XState.
# src/helpers/toggle-machine.ts
import { createMachine } from 'xstate';
export const toggleMachine = createMachine({
id: 'toggle',
initial: 'active',
states: {
inactive: { on: { toggle: 'active' } },
active: { on: { toggle: 'inactive' } }
}
});
# src/components/toggle/toggle.tsx
Add a state
property to your component, decorated with @State
so that it triggers a re-render when changed.
On componentWillLoad
, interpret the toggleMachine
and listen for state transitions.
After a transition has occurred, the state
property is set to the machine's new state, triggering a re-render.
import { Component, h, State } from "@stencil/core";
import { interpret } from "xstate";
import { toggleMachine } from "../helpers/toggle-machine";
@Component({
tag: "my-toggle",
styleUrl: "toggle.css",
shadow: true
})
export class Toggle {
private _service = interpret(toggleMachine);
@State() state = this._service.getSnapshot();
componentWillLoad() {
this._service.subscribe(state => {
this.state = state;
});
this._service.start();
}
disconnectedCallback() {
this._service.stop();
}
render() {
const { send } = this._service;
return (
<button onClick={() => send("toggle")}>
{this.state.value === "inactive" ? "Off" : "On"}
</button>
);
}
}
Your html page:
<html>
<head>
<script type="module" src="/build/my-toggle.esm.js"></script>
<script nomodule src="/build/my-toggle.js"></script>
</head>
<body>
<my-toggle></my-toggle>
</body>
</html>