diff --git a/packages/node_modules/overmind-react/src/index.test.tsx b/packages/node_modules/overmind-react/src/index.test.tsx index edc32336..c0223e3d 100644 --- a/packages/node_modules/overmind-react/src/index.test.tsx +++ b/packages/node_modules/overmind-react/src/index.test.tsx @@ -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', () => { diff --git a/packages/node_modules/overmind-react/src/index.ts b/packages/node_modules/overmind-react/src/index.ts index 8f84675c..2faa2d2c 100644 --- a/packages/node_modules/overmind-react/src/index.ts +++ b/packages/node_modules/overmind-react/src/index.ts @@ -12,6 +12,8 @@ import { // @ts-ignore useState, useLayoutEffect, + createContext, + useContext, } from 'react' import { IMutation } from 'proxy-state-tree' @@ -38,14 +40,21 @@ export interface IConnect { } } +const context = createContext>({} as Overmind< + Configuration +>) let nextComponentId = 0 -export const createHook = >( - overmind: A +export const Provider: React.ProviderExoticComponent< + React.ProviderProps> +> = context.Provider + +export const createHook = ( + overmindInstance?: Overmind ): (() => { - state: A['state'] - actions: A['actions'] - effects: A['effects'] + state: TApp['state'] + actions: TApp['actions'] + effects: TApp['effects'] addMutationListener: (cb: (mutation: IMutation) => void) => () => void }) => { let currentComponentInstanceId = 0 @@ -61,6 +70,9 @@ export const createHook = >( } return () => { + const overmind = (overmindInstance || useContext(context)) as Overmind< + Config + > const component = useCurrentComponent() const name = component.name component.__componentId = diff --git a/packages/overmind-website/examples/guide/usingovermindwithreact/hook_provider.ts b/packages/overmind-website/examples/guide/usingovermindwithreact/hook_provider.ts new file mode 100644 index 00000000..25898b36 --- /dev/null +++ b/packages/overmind-website/examples/guide/usingovermindwithreact/hook_provider.ts @@ -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 {} +} + +export const overmind = new Overmind(config) + +export const useOvermind = createHook() + `, + }, + { + 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(( + + + +), 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
{state.title}
+} + +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
+} + +export default App +`, + }, + ] diff --git a/packages/overmind-website/guides/beginner/06_usingovermindwithreact.md b/packages/overmind-website/guides/beginner/06_usingovermindwithreact.md index 25c725ca..d3ffdbd1 100644 --- a/packages/overmind-website/guides/beginner/06_usingovermindwithreact.md +++ b/packages/overmind-website/guides/beginner/06_usingovermindwithreact.md @@ -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" }) ``` \ No newline at end of file