Skip to content

Commit dd90e6f

Browse files
feat(overmind-react): add provider
1 parent a9d87fc commit dd90e6f

File tree

4 files changed

+114
-6
lines changed

4 files changed

+114
-6
lines changed

packages/node_modules/overmind-react/src/index.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Overmind, IAction } from 'overmind'
22
import * as React from 'react'
33
import * as renderer from 'react-test-renderer'
4-
import { IConnect, createConnect } from './'
4+
import { IConnect, createConnect, createHook, Provider } from './'
55

66
describe('React', () => {
77
test('should connect state and actions to stateless components', () => {

packages/node_modules/overmind-react/src/index.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
// @ts-ignore
1313
useState,
1414
useLayoutEffect,
15+
createContext,
16+
useContext,
1517
} from 'react'
1618
import { IMutation } from 'proxy-state-tree'
1719

@@ -38,14 +40,21 @@ export interface IConnect<Config extends Configuration> {
3840
}
3941
}
4042

43+
const context = createContext<Overmind<Configuration>>({} as Overmind<
44+
Configuration
45+
>)
4146
let nextComponentId = 0
4247

43-
export const createHook = <A extends Overmind<Configuration>>(
44-
overmind: A
48+
export const Provider: React.ProviderExoticComponent<
49+
React.ProviderProps<Overmind<Configuration>>
50+
> = context.Provider
51+
52+
export const createHook = <Config extends Configuration>(
53+
overmindInstance?: Overmind<Config>
4554
): (() => {
46-
state: A['state']
47-
actions: A['actions']
48-
effects: A['effects']
55+
state: TApp<Config>['state']
56+
actions: TApp<Config>['actions']
57+
effects: TApp<Config>['effects']
4958
addMutationListener: (cb: (mutation: IMutation) => void) => () => void
5059
}) => {
5160
let currentComponentInstanceId = 0
@@ -61,6 +70,9 @@ export const createHook = <A extends Overmind<Configuration>>(
6170
}
6271

6372
return () => {
73+
const overmind = (overmindInstance || useContext(context)) as Overmind<
74+
Config
75+
>
6476
const component = useCurrentComponent()
6577
const name = component.name
6678
component.__componentId =
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
export default (ts) =>
2+
ts
3+
? [
4+
{
5+
fileName: 'overmind/index.ts',
6+
code: `
7+
import { Overmind, IConfig } from 'overmind'
8+
import { createHook } from 'overmind-react'
9+
import { state } from './state'
10+
import * as actions from './actions'
11+
12+
const config = {
13+
state,
14+
actions
15+
}
16+
17+
declare module 'overmind' {
18+
interface Config extends IConfig<typeof config> {}
19+
}
20+
21+
export const overmind = new Overmind(config)
22+
23+
export const useOvermind = createHook<typeof config>()
24+
`,
25+
},
26+
{
27+
fileName: 'components/index.tsx',
28+
code: `
29+
import * as React from 'react'
30+
import { render } from 'react-dom'
31+
import { Provider } from 'overmind-react'
32+
import { overmind } from './overmind'
33+
import App from './components/App'
34+
35+
render((
36+
<Provider value={overmind}>
37+
<App />
38+
</Provider>
39+
), document.querySelector('#app'))
40+
`,
41+
},
42+
{
43+
fileName: 'components/App.tsx',
44+
code: `
45+
import * as React from 'react'
46+
import { useOvermind } from '../overmind'
47+
48+
const App: React.FunctionComponent = () => {
49+
const { state } = useOvermind()
50+
51+
return <div>{state.title}</div>
52+
}
53+
54+
export default App
55+
`,
56+
},
57+
]
58+
: [
59+
{
60+
fileName: 'overmind/index.js',
61+
code: `
62+
import { Overmind } from 'overmind'
63+
import { createHook } from 'overmind-react'
64+
65+
const overmind = new Overmind({
66+
state: {},
67+
actions: {}
68+
})
69+
70+
export const useOvermind = createHook(overmind)
71+
`,
72+
},
73+
{
74+
fileName: 'components/App.jsx',
75+
code: `
76+
import React from 'react'
77+
import { useOvermind } from '../overmind'
78+
79+
const App = () => {
80+
const { state, actions, effects, addMutationListener } = useOvermind()
81+
82+
return <div />
83+
}
84+
85+
export default App
86+
`,
87+
},
88+
]

packages/overmind-website/guides/beginner/06_usingovermindwithreact.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,12 @@ You can also here use the traditional approach adding a subscription to any upda
6666

6767
```marksy
6868
h(Example, { name: "guide/usingovermindwithreact/hook_effect_subscription" })
69+
```
70+
71+
### Provider
72+
73+
With the hooks API you can also expose the Overmind instance with a Provider. This detaches the overmind instance from the actual **useOvermind** hook. It is rather consumed from the React context. This makes it easier to test components and you can use component libraries which is built for Overmind.
74+
75+
```marksy
76+
h(Example, { name: "guide/usingovermindwithreact/hook_provider" })
6977
```

0 commit comments

Comments
 (0)