xstate with context provider

Solutions on MaxInterview for xstate with context provider by the best coders in the world

showing results for - "xstate with context provider"
Everett
07 Aug 2017
1import React, { useContext } from 'react'
2import ReactDOM from 'react-dom'
3import { MachineConfig } from 'xstate'
4import { assign } from 'xstate/lib/actions'
5import { useMachine, TCreateContext } from './use-machine'
6
7type TContext = {
8  counter: number
9}
10
11type TSchema = {
12  states: {
13    Off: {},
14    On: {}
15  }
16}
17
18type TEvent = {
19  type: 'Tick'
20}
21
22const incAction = assign<TContext>(context => ({ counter: context.counter + 1 }))
23
24const machineConfig: MachineConfig<TContext, TSchema, TEvent> = {
25  initial: 'Off',
26  context: {
27    counter: 0
28  },
29  states: {
30    Off: { on: { Tick: { target: 'On', actions: [incAction, 'sideEffect'] } } },
31    On: { on: { Tick: { target: 'Off', actions: incAction } } }
32  }
33}
34
35type TMachine = TCreateContext<TContext, TSchema, TEvent>
36
37const MachineContext = React.createContext<TMachine>({} as TMachine)
38
39function App() {
40  const machine = useMachine<TContext, TSchema, TEvent>(machineConfig, {
41    actions: {
42      sideEffect: () => console.log('sideEffect')
43    }
44  })
45
46  function sendTick() {
47    machine.send('Tick')
48  }
49
50  return (
51    <div className="App">
52      <span
53        style={{
54          backgroundColor: machine.state.matches('Off') ? 'red' : 'yellow'
55        }}
56      >
57        {machine.state.matches('Off') ? 'Off' : 'On'}
58      </span>
59      <button onClick={sendTick}>Tick</button>
60      Pressed: {machine.context.counter} times
61      <MachineContext.Provider value={machine}>
62        <div className="childs">
63          <Child />
64        </div>
65      </MachineContext.Provider>
66    </div>
67  )
68}
69
70function Child() {
71  const machine = useContext(MachineContext)
72  return (
73    <div>
74      <div>
75        Child state: {machine.state.matches('Off') ? 'Off' : 'On'}
76      </div>
77      <div>Child count: {machine.context.counter}</div>
78      <OtherChild />
79    </div>
80  )
81}
82
83function OtherChild() {
84  const machine = useContext(MachineContext)
85
86  function sendTick() {
87    machine.send('Tick')
88  }
89  return (
90    <div>
91      <div>
92        OtherChild state: {machine.state.matches('Off') ? 'Off' : 'On'}
93      </div>
94      <div>OtherChild count: {machine.context.counter}</div>
95      <button onClick={sendTick}>Tick 2</button>
96    </div>
97  )
98}
99
100const rootElement = document.getElementById('root')
101ReactDOM.render(<App />, rootElement)
102