Skip to content

Commit

Permalink
feat(overmind-react): add provider
Browse files Browse the repository at this point in the history
  • Loading branch information
christianalfoni committed Jan 15, 2019
1 parent a9d87fc commit dd90e6f
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 6 deletions.
2 changes: 1 addition & 1 deletion packages/node_modules/overmind-react/src/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Overmind, IAction } from 'overmind'
import * as React from 'react'
import * as renderer from 'react-test-renderer'
import { IConnect, createConnect } from './'
import { IConnect, createConnect, createHook, Provider } from './'

describe('React', () => {
test('should connect state and actions to stateless components', () => {
Expand Down
22 changes: 17 additions & 5 deletions packages/node_modules/overmind-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
// @ts-ignore
useState,
useLayoutEffect,
createContext,
useContext,
} from 'react'
import { IMutation } from 'proxy-state-tree'

Expand All @@ -38,14 +40,21 @@ export interface IConnect<Config extends Configuration> {
}
}

const context = createContext<Overmind<Configuration>>({} as Overmind<
Configuration
>)
let nextComponentId = 0

export const createHook = <A extends Overmind<Configuration>>(
overmind: A
export const Provider: React.ProviderExoticComponent<
React.ProviderProps<Overmind<Configuration>>
> = context.Provider

export const createHook = <Config extends Configuration>(
overmindInstance?: Overmind<Config>
): (() => {
state: A['state']
actions: A['actions']
effects: A['effects']
state: TApp<Config>['state']
actions: TApp<Config>['actions']
effects: TApp<Config>['effects']
addMutationListener: (cb: (mutation: IMutation) => void) => () => void
}) => {
let currentComponentInstanceId = 0
Expand All @@ -61,6 +70,9 @@ export const createHook = <A extends Overmind<Configuration>>(
}

return () => {
const overmind = (overmindInstance || useContext(context)) as Overmind<
Config
>
const component = useCurrentComponent()
const name = component.name
component.__componentId =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
export default (ts) =>
ts
? [
{
fileName: 'overmind/index.ts',
code: `
import { Overmind, IConfig } from 'overmind'
import { createHook } from 'overmind-react'
import { state } from './state'
import * as actions from './actions'
const config = {
state,
actions
}
declare module 'overmind' {
interface Config extends IConfig<typeof config> {}
}
export const overmind = new Overmind(config)
export const useOvermind = createHook<typeof config>()
`,
},
{
fileName: 'components/index.tsx',
code: `
import * as React from 'react'
import { render } from 'react-dom'
import { Provider } from 'overmind-react'
import { overmind } from './overmind'
import App from './components/App'
render((
<Provider value={overmind}>
<App />
</Provider>
), document.querySelector('#app'))
`,
},
{
fileName: 'components/App.tsx',
code: `
import * as React from 'react'
import { useOvermind } from '../overmind'
const App: React.FunctionComponent = () => {
const { state } = useOvermind()
return <div>{state.title}</div>
}
export default App
`,
},
]
: [
{
fileName: 'overmind/index.js',
code: `
import { Overmind } from 'overmind'
import { createHook } from 'overmind-react'
const overmind = new Overmind({
state: {},
actions: {}
})
export const useOvermind = createHook(overmind)
`,
},
{
fileName: 'components/App.jsx',
code: `
import React from 'react'
import { useOvermind } from '../overmind'
const App = () => {
const { state, actions, effects, addMutationListener } = useOvermind()
return <div />
}
export default App
`,
},
]
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,12 @@ You can also here use the traditional approach adding a subscription to any upda

```marksy
h(Example, { name: "guide/usingovermindwithreact/hook_effect_subscription" })
```

### Provider

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.

```marksy
h(Example, { name: "guide/usingovermindwithreact/hook_provider" })
```

0 comments on commit dd90e6f

Please sign in to comment.