Joel and Chance chat about the big ideas of State Management and when you should start implementing a State Machine in your application. Chance gives a walkthrough of how Reach UI handles State, how the Listbox
component was built, and how reading the React UI source code is an excellent source of learning material.
Listbox
component was the most challenging; a Listbox
presents a list of selectable options in a popover, which is toggled on or off by a button.@reach/menu-button
except that ListboxOption
components hold a value.mouseDown
. Unlike with the native select
- Web/HTML/Element/select@xstate/fsm
, a miniature version of XState.Transition
:// https://github.com/reach/reach-ui/blob/a376daec462ccb53d33f4471306dff35383a03a5/packages/tooltip/src/index.tsx
/**
* Finds the next state from the current state + action. If the chart doesn't
* describe that transition, it will throw.
*
* It also manages lifecycles of the machine, (enter/leave hooks on the state
* chart)
*
* @param event
* @param payload
*/
const transition: Transition = (event, payload) => {
let stateDef = chart.states[state];
let nextState = stateDef && stateDef.on && stateDef.on[event];
// Really useful for debugging
// console.log({ event, state, nextState, contextId: context.id });
// !nextState && console.log('no transition taken')
if (!nextState) {
return;
}
if (stateDef && stateDef.leave) {
stateDef.leave();
}
if (payload) {
context = payload;
}
let nextDef = chart.states[nextState];
if (nextDef && nextDef.enter) {
nextDef.enter();
}
state = nextState;
notify();
};
StateChart
, which takes the main ideas of a State Machine to handle several events.// https://github.com/reach/reach-ui/blob/a376daec462ccb53d33f4471306dff35383a03a5/packages/tooltip/src/index.tsx
const chart: StateChart = {
initial: IDLE,
states: {
[IDLE]: {
enter: clearContextId,
on: {
[MOUSE_ENTER]: FOCUSED,
[FOCUS]: VISIBLE,
},
},
[FOCUSED]: {
enter: startRestTimer,
leave: clearRestTimer,
on: {
[MOUSE_MOVE]: FOCUSED,
[MOUSE_LEAVE]: IDLE,
[MOUSE_DOWN]: DISMISSED,
[BLUR]: IDLE,
[REST]: VISIBLE,
},
},
...