ReduxKotlin

ReduxKotlin

  • Getting Started
  • API
  • FAQ
  • Github
  • Need help?

›API Reference

Introduction

  • Getting Started with Redux
  • Motivation
  • Core Concepts
  • Three Principles
  • Threading
  • Learning Resources
  • Ecosystem
  • Examples

Basic Tutorial

  • Basic Tutorial: Intro
  • Actions
  • Reducers
  • Store
  • Data flow

Advanced Tutorial

  • Advanced Tutorial: Intro
  • Async Actions
  • Middleware

FAQ

  • FAQ Index
  • General
  • Reducers
  • Store Setup
  • Multiplatform

Other

  • Glossary
  • Troubleshooting
  • Feedback

API Reference

  • API Reference
  • createStore
  • createThreadSafeStore
  • createSameThreadEnforcedStore
  • Store
  • applyMiddleware
  • compose

applyMiddleware(vararg middlewares: Middleware<State>): StoreEnhancer<State>

Middleware is the suggested way to extend Redux with custom functionality. Middleware lets you wrap the store's dispatch method for fun and profit. The key feature of middleware is that it is composable. Multiple middleware can be combined together, where each middleware requires no knowledge of what comes before or after it in the chain.

The most common use case for middleware is to support asynchronous actions without much boilerplate code. It does so by letting you dispatch async actions in addition to normal actions.

For example, redux-thunk lets the action creators invert control by dispatching functions. They would receive dispatch as an argument and may call it asynchronously. Such functions are called thunks. Currently that is the only middleware available for ReduxKotlin, though others could be added easily.

Middleware is not baked into createStore and is not a fundamental part of the Redux architecture, but we consider it useful enough to be supported right in the core. This way, there is a single standard way to extend dispatch in the ecosystem, and different middleware may compete in expressiveness and utility.

Arguments

  • vararg middleware: Middleware<State> (arguments): Functions that conform to the Redux middleware API. For ReduxKotlin this is a typealias:
typealias Middleware<State> = (store: Store<State>) -> (next: Dispatcher) -> (action: Any) -> Any

Each middleware receives Store's dispatch and getState functions as named arguments, and returns a function. That function will be given the next middleware's dispatch method, and is expected to return a function of action calling next(action) with a potentially different argument, or at a different time, or maybe not calling it at all. The last middleware in the chain will receive the real store's dispatch method as the next parameter, thus ending the chain.

Returns

(Function) A store enhancer that applies the given middleware. The store enhancer signature is:

typealias StoreEnhancer<State> = (StoreCreator<State>) -> StoreCreator<State>

but the easiest way to apply it is to pass it to createThreadSafeStore() as the last enhancer argument.

Example: Custom Logger Middleware

fun loggerMiddleware2(store: Store<AppState>) = { next: Dispatcher ->
    { action: Any ->
        Logger.d("will dispatch $action")
        
        // Call the next dispatch method in the middleware chain.
        val returnValue = next(action)
        Logger.d("state after dispatch: ${store.state}")
        
        // This will likely be the action itself, unless
        // a middleware further in chain changed it.
        result
    }
}


val store = createThreadSafeStore(todos, AppState.INITIAL_STATE, applyMiddleware(::logger))

store.dispatch(AddTodoAction(text = "Understand middleware"))
// (These lines will be logged by the middleware:)
// will dispatch: AddTodoAction(text = "Understand middleware")
// state after dispatch: AppState(todos = [AddTodo(text = "Understand middleware")]

Tips

  • Middleware only wraps the store's dispatch function. Technically, anything a middleware can do, you can do manually by wrapping every dispatch call, but it's easier to manage this in a single place and define action transformations on the scale of the whole project.

  • If you use other store enhancers in addition to applyMiddleware, make sure to put applyMiddleware before them in the composition chain because the middleware is potentially asynchronous.

  • Ever wondered what applyMiddleware itself is? It ought to be an extension mechanism more powerful than the middleware itself. Indeed, applyMiddleware is an example of the most powerful Redux extension mechanism called store enhancers. It is highly unlikely you'll ever want to write a store enhancer yourself. Another example of a store enhancer is redux-devtools. Middleware is less powerful than a store enhancer, but it is easier to write.

  • Middleware sounds much more complicated than it really is. The only way to really understand middleware is to see how the existing middleware works, and try to write your own. The function nesting can be intimidating, but most of the middleware you'll find are, in fact, 10-liners, and the nesting and composability is what makes the middleware system powerful.

  • To apply multiple store enhancers, you may use compose().

← PreviousNext →
ReduxKotlin
Docs
Getting StartedCore ConceptsBasicsAdvanced
Community
#redux slackTrello board
More
GitHubStar
Thank you to Dan Abramov and the Redux.js.org documentation authors from which this was forked.
Some icons copyright Font Awesome and Noun Project (Hassan ali, ProSymbols)