With explicit stateswe have hooks to trigger side effects moving into specific states. By making side effects reactive to state, all actions needs to go by our reducer before any side effect can happen. This constraint creates more predictability as running side effects is not "at the command of the environment and the user".
import { useStateEffect, useCommandEffect } from 'react-states'
// Skipping the typing and stuff
const FeatureProvider: React.FC = () => {
const feature = useReducer({...})
const [state, dispatch] = feature
useStateEffect(state, 'STATE_A', () => {
// I will trigger whenever the feature moves into the
// STATE_A state
})
useStateEffect(state, 'STATE_B', () => {
// I will trigger whenever the feature moves into the
// STATE_B state
return () => {
// I trigger when STATE_B is exited or the component
// unmounts
}
})
useStateEffect(state, ['STATE_A', 'STATE_B'], () => {
// I will run when either state is entered
return () => {
// I will run when moving from an entered state to some other state
}
})
useCommandEffect(state, 'SOME_COMMAND', ({ item }) => {
// I will run when a command is returned
})
return (
<Context.Provider value={feature}>
{children}
</Context.Provider>
)
}