Skip to content

Instantly share code, notes, and snippets.

@christianalfoni
Last active September 2, 2021 14:44
Show Gist options
  • Save christianalfoni/842df6eb5a7d115b52e9462849d5ed85 to your computer and use it in GitHub Desktop.
Save christianalfoni/842df6eb5a7d115b52e9462849d5ed85 to your computer and use it in GitHub Desktop.

Migration

The next version of the docs can be found here: https://overmindjs.org/v/v28

Overmind typing

The implicit typing has been completely removed, meaning you have to explicitly type your application. That said, the explicit typing is way simpler then in the previous version. This is all of it:

import { IContext } from 'overmind'

export const config = {
  // Create config as normal
}

export type Context = IContext<{
  state: typeof config.state,
  actions: typeof config.actions,
  effects: typeof config.effects
}>

Actions typing

Now actions are typed only using the Context type.

import { Context } from '../'

export const myAction = ({ state, effects, actions }: Context, somePayload: string) => {}

The only thing you have to specifically type in Overmind actions now is the first argument, using Context.

Operators

Actions are now interoperable with operators. That means a valid operator would be:

export const foo = pipe(
  // Inline action
  (_, payload: string) => Number(payload),
  // Referencing some existing action
  setNumberAction
)

That means a few operators has been removed as they can be solved by just using a simple action. Those operators are mutate, map, run and forEach. The goal of operators is to enhance and build upon actions.

React Hooks

Now you pass Context to the factories:

import {
  createStateHook,
  createActionsHook,
  createEffectsHook,
  createReactionHook
} from 'overmind-react'

export type Context = (...)

export const useAppState = createStateHook<Context>()
export const useActions = createActionsHook<Context>()
export const useEffects = createEffectsHook<Context>()
export const useReaction = createReactionHook<Context>()

React

The Higher Order Component has been removed as this is not the encouraged approach by the React Team.

The useOvermind hook has been removed in favour of the explicit hooks. This is partly optimisation reasons, but also improved API of createStateHook which now allows "scoped tracking".

Statemachines

Instead of having a single generic signature that tries to solve flexibility and still be declarative, the statemachines rather now has two signatures. One for ultimate flexibility and one for ultimate declarativeness:

// Now you express in what state what events are to be dealt with
const machine = statemachine({
  SOME_STATE: {
    SOME_EVENT: (event, state) => {}
  }
})

// Or you do it from scratch
const machine = statemachine((event, state) => {
  // Check event and current state to optionally return a new state
})

onInitialize

There is no onInitialize anymore. You rather use an action named onInitializeOvermind and put it with your other actions. Due to typing limitation the Overmind instance passed to this action can not be typed. Read more in extended context.

Extended context

You now have reaction, addMutationListener and addFlushListener available on the context in actions/operators. Now that Overmind supports plain functions in the state tree it will become more common to store the disposers of these listeners in the state tree itself to more effectively deal with them across actions and state

@lavir
Copy link

lavir commented Aug 26, 2021

In the migration guide is missed very important information such as:

fork has new signature:

pipe(
  // "type" is a property on the object on the pipe
  fork('type', {
    FOO: (context: Context, event) => {
      event // Is now typed as FooEvent
    },
    BAR: (context: context, event) => {
      event // Is now typed as BarEvent
    } 
  })
)

parallel now actually returns an array to the pipe with the results of each operator

cerebral/overmind#481

@stivncastillo
Copy link

What is the best approach to migrate AsyncActions?

export const MyAction: AsyncAction<{param: string}, boolean> = async ({ state, effects }, { orderId, receivingApp }) => { return await ....; };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment