Skip to content

Instantly share code, notes, and snippets.

@Ivannnnn
Last active June 11, 2020 10:49
Show Gist options
  • Save Ivannnnn/85a16bd873e031f8c8616eb754b43b92 to your computer and use it in GitHub Desktop.
Save Ivannnnn/85a16bd873e031f8c8616eb754b43b92 to your computer and use it in GitHub Desktop.
const machine = {
empty: {
SELECT: {
to: 'loading',
action: (state, dispatch) => {
interval.stop()
loadBook().then((book) => dispatch('SELECT_SUCCESS', book))
return { ...state, title: null, progress: 0 }
},
},
loading: {
SELECT_SUCCESS: {
to: 'paused',
action: (state, dispatch, book) => {
return { ...state, title: book.title }
},
},
SELECT_FAILURE: { to: 'empty' },
},
paused: {
SELECT,
PLAY: {
to: 'playing'
},
SET_PROGRESS: {
action: (state, _, progress) => ({ ...state, progress }),
},
},
}
const initialStatus = 'empty'
const App = () => {
const [status, state, dispatch] = useStateMachine(machine, initialStatus, {
progress: 10,
title: null,
})
// dispatch('SELECT')
}
const useStateMachine = (machine, initialStatus, initialState) => {
const [{ status, ...state }, setState] = useState({
status: initialStatus,
...initialState,
})
const dispatch = (actionName, ...args) => {
setState((state) => {
const next = machine[state.status][actionName]
if (!next) return state
if (next.action) {
return {
...(next.action(state, dispatch, ...args) || state),
status: next.to || state.status,
}
} else if (next.to !== state.status) {
return { ...state, status: next.to }
} else {
return state
}
})
}
return [status, state, dispatch]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment