pub trait MiddleWare<State, Action, Inner, InnerAction = Action> where
    Action: Send + 'static,
    State: Send + 'static,
    InnerAction: Send + 'static,
    Inner: StoreApi<State, InnerAction> + Send + Sync
{ fn dispatch<'life0, 'life1, 'async_trait>(
        &'life0 self,
        action: Action,
        inner: &'life1 Arc<Inner>
    ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: 'async_trait
; fn init<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        inner: &'life1 Arc<Inner>
    ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
    where
        'life0: 'async_trait,
        'life1: 'async_trait,
        Self: Send + 'async_trait
, { ... } }
Expand description

Middlewares are the way to introduce side effects to the redux store.

Some examples of middleware could be:

  • Logging middleware, log every action
  • Api call middleware, make an api call when a certain action is send

Notice that there’s an Action and an InnerAction. This enables us to send actions which are not of the same type as the underlying store.

Logging middleware example

use async_trait::async_trait;
use std::sync::Arc;
use redux_rs::{MiddleWare, Store, StoreApi};

#[derive(Default)]
struct Counter(i8);

#[derive(Debug)]
enum Action {
    Increment,
    Decrement
}

fn counter_reducer(state: Counter, action: Action) -> Counter {
    match action {
        Action::Increment => Counter(state.0 + 1),
        Action::Decrement => Counter(state.0 - 1),
    }
}

// Logger which logs every action before it's dispatched to the store
struct LoggerMiddleware;
#[async_trait]
impl<Inner> MiddleWare<Counter, Action, Inner> for LoggerMiddleware
    where
Inner: StoreApi<Counter, Action> + Send + Sync
{
    async fn dispatch(&self, action: Action, inner: &Arc<Inner>)
    {
        // Print the action
        println!("Before action: {:?}", action);

        // Dispatch the action to the underlying store
        inner.dispatch(action).await;
    }
}

// Create a new store and wrap it with out new LoggerMiddleware
let store = Store::new(counter_reducer).wrap(LoggerMiddleware).await;

// Dispatch an increment action
// The console should print our text
store.dispatch(Action::Increment).await;

// Dispatch an decrement action
// The console should print our text
store.dispatch(Action::Decrement).await;

Required methods

This method is called every time an action is dispatched to the store.

You have the possibility to modify/cancel the action entirely. You could also do certain actions before or after launching a specific/every action.

NOTE: In the middleware you need to call inner.dispatch(action).await; otherwise no actions will be send to the underlying StoreApi (and eventually store)

Provided methods

This method is called the moment the middleware is wrapped around an underlying store api. Initialization could be done here.

For example, you could launch an “application started” action

Implementors