OVERMIND
v23
v23
  • Overmind
  • Introduction
  • Quickstart
  • How to learn
  • Videos
  • FAQ
  • Core
    • Devtools
    • Configuration
    • State
    • Actions
    • Effects
    • Operators
    • Statecharts
    • Server Side Rendering
    • Typescript
  • views
    • React
    • Angular
    • Vue
  • Addons
    • GraphQL
  • Guides
    • Connecting components
    • Connecting to React Native
    • Managing lists
    • State first routing
    • Move to Typescript
    • Testing
  • API
    • action
    • addFlushListener
    • addMutationListener
    • createOvermind
    • createOvermindMock
    • createOvermindSSR
    • derive
    • effects
    • events
    • json
    • lazy
    • merge
    • namespaced
    • onInitialize
    • operators
    • reaction
    • rehydrate
    • statecharts
Powered by GitBook
On this page
  • APPLICATION INSIGHT
  • A SINGLE STATE TREE
  • SEPARATION OF LOGIC
  • SAFE AND PREDICTABLE CHANGES
  • COMPLEXITY TOOLS
  • SNAPSHOT TESTING OF LOGIC
  • WE WROTE THE TYPING
  • RUNNING CODESANDBOX

Overmind

frictionless state management

NextIntroduction

Last updated 4 years ago

Web application development is about defining, changing and consuming state to produce a user experience. Overmind aims for a developer experience where that is all you focus on, reducing the orchestration of state management to a minimum. Making you a happier and more productive developer!

APPLICATION INSIGHT

A SINGLE STATE TREE

Building your application with a single state tree is the most straight forward mental model. You get a complete overview, but can still organize the state by namespacing it into domains. The devtools allows you to edit and mock out state.

{
  isAuthenticating: false,
  dashboard: {
    issues: [],
    selectedIssueId: null,
  },
  user: null,
  form: new Form()
}

SEPARATION OF LOGIC

Separate 3rd party APIs and logic not specific to your application by using effects. This will keep your application logic pure and without low level APIs cluttering your code.

export const fetchItems = async () {
    const response = await fetch('/api/items')

    return response.json()
  }
}
export const loadApp = ({ state, effects }) => {
  state.items = await effects.api.fetchItems()
}

SAFE AND PREDICTABLE CHANGES

When you build applications that perform many state changes things can get out of hand. In Overmind you can only perform state changes from actions and all changes are tracked by the development tool.

export const getItems = async ({ state, effects }) => {
  state.isLoadingItems = true
  state.items = await effects.api.fetchItems()
  state.isLoadingItems = false
}

COMPLEXITY TOOLS

Even though Overmind can create applications with only plain state and actions, you can use opt-in tools like functional operators, statecharts, statemachines and state values defined as a class, to manage complexities of your application.

export const search = pipe(
  mutate(({ state }, query) => {
    state.query = query
  }),
  filter((_, query) => query.length > 2),
  debounce(200),
  mutate(async ({ state, effects }, query) => {
    state.isSearching = true
    state.searchResult = await effects.getSearchResult(query)
    state.isSearching = false
  })
)
const loginChart = {
  initial: 'LOGIN',
  states: {
    LOGIN: {
      on: {
        changeUsername: null,
        changePassword: null,
        login: 'AUTHENTICATING'
      }
    },
    AUTHENTICATING: {
      on: {
        resolveUser: 'AUTHENTICATED',
        rejectUser: 'ERROR'
      }
    },
    AUTHENTICATED: {
      on: {
        logout: 'LOGIN'
      }
    },
    ERROR: {
      on: {
        tryAgain: 'LOGIN'
      }
    }
  }
}
export const state = {
  mode: statemachine({
    initial: 'unauthenticated',
    states: {
      unauthenticated: ['authenticating'],
      authenticating: ['unauthenticated', 'authenticated'],
      authenticated: ['unauthenticating'],
      unauthenticating: ['unauthenticated', 'authenticated']
    }
  }),
  user: null,
  error: null
}
class LoginForm() {
  private username = ''
  private password = ''
  private validationError = ''
  changeUsername(username) {
    this.username = username
  }
  changePassword(password) {
    if (!password.match([0-9]) {
      this.validationError = 'You need some numbers in your password'
    }
    this.password = password
  }
  isValid() {
    return Boolean(this.username && this.password) 
  }
}

export const state = {
  loginForm: new LoginForm()
}

SNAPSHOT TESTING OF LOGIC

Bring in your application configuration of state, effects and actions. Create mocks for any effects. Take a snapshot of mutations performed in an action to ensure all intermediate states are met.

import { createOvermindMock } from 'overmind'
import { config } from './'

test('should get items', async () => {
  const overmind = createOvermindMock(config, {
    api: {
      fetchItems: () => Promise.resolve([{ id: 0, title: "foo" }])
    }
  })

  await overmind.actions.getItems()

  expect(overmind.mutations).toMatchSnapshot()
})

WE WROTE THE TYPING

Overmind has you covered on typing. If you choose to use Typescript the whole API is built for excellent typing support. You will not spend time telling Typescript how your app works, Typescript will tell you!

RUNNING CODESANDBOX

Develop the application state, effects and actions without leaving , or use the standalone development tool. Everything that happens in your app is tracked and you can seamlessly code and run logic to verify that everything works as expected without necessarily having to implement UI.

Overmind is running the main application of . Codesandbox, with its state and effects complexity, benefits greatly combining Overmind and Typescript.

VS Code
codesandbox.io
LogoRelease v23 (OvermindJS) | overmindjs ChangelogChangefeed