Struct redux_rs::middlewares::thunk::ThunkMiddleware
source · [−]pub struct ThunkMiddleware;
Expand description
Thunk middleware
Thunk middleware enables us to introduce side-effects in a redux application.
With this middleware you can dispatch actions and thunks to your store.
Fn example
use async_trait::async_trait;
use std::sync::Arc;
use std::time::Duration;
use redux_rs::{Store, StoreApi};
use redux_rs::middlewares::thunk::{ActionOrThunk, ThunkMiddleware, Thunk};
use tokio::time::sleep;
#[derive(Default, Debug, PartialEq)]
struct UserState {
users: Vec<User>,
}
#[derive(Clone, Debug, PartialEq)]
struct User {
id: u8,
name: String,
}
enum UserAction {
UsersLoaded { users: Vec<User> },
}
fn user_reducer(state: UserState, action: UserAction) -> UserState {
match action {
UserAction::UsersLoaded { users } => UserState { users },
}
}
async fn load_users(store_api: Arc<impl StoreApi<UserState, UserAction>>) {
// Emulate api call by delaying for 100 ms
sleep(Duration::from_millis(100)).await;
// Return the data to the store
store_api
.dispatch(UserAction::UsersLoaded {
users: vec![
User {
id: 0,
name: "John Doe".to_string(),
},
User {
id: 1,
name: "Jane Doe".to_string(),
},
],
})
.await;
}
let store = Store::new(user_reducer).wrap(ThunkMiddleware).await;
store.dispatch(ActionOrThunk::Thunk(Box::new(load_users))).await;
let users = store.select(|state: &UserState| state.users.clone()).await;
assert_eq!(users, vec![]);
sleep(Duration::from_millis(200)).await;
let users = store.select(|state: &UserState| state.users.clone()).await;
assert_eq!(
users,
vec![
User {
id: 0,
name: "John Doe".to_string(),
},
User {
id: 1,
name: "Jane Doe".to_string(),
},
]
);
Trait example
use async_trait::async_trait;
use std::sync::Arc;
use std::time::Duration;
use redux_rs::{Store, StoreApi};
use redux_rs::middlewares::thunk::{ActionOrThunk, ThunkMiddleware, Thunk};
use tokio::time::sleep;
#[derive(Default, Debug, PartialEq)]
struct UserState {
users: Vec<User>,
}
#[derive(Clone, Debug, PartialEq)]
struct User {
id: u8,
name: String,
}
enum UserAction {
UsersLoaded { users: Vec<User> },
}
fn user_reducer(state: UserState, action: UserAction) -> UserState {
match action {
UserAction::UsersLoaded { users } => UserState { users },
}
}
struct LoadUsersThunk;
#[async_trait]
impl<Api> Thunk<UserState, UserAction, Api> for LoadUsersThunk
where
Api: StoreApi<UserState, UserAction> + Send + Sync + 'static,
{
async fn execute(&self, store_api: Arc<Api>) {
// Emulate api call by delaying for 100 ms
sleep(Duration::from_millis(100)).await;
// Return the data to the store
store_api
.dispatch(UserAction::UsersLoaded {
users: vec![
User {
id: 0,
name: "John Doe".to_string(),
},
User {
id: 1,
name: "Jane Doe".to_string(),
},
],
})
.await;
}
}
let store = Store::new(user_reducer).wrap(ThunkMiddleware).await;
store.dispatch(ActionOrThunk::Thunk(Box::new(LoadUsersThunk))).await;
let users = store.select(|state: &UserState| state.users.clone()).await;
assert_eq!(users, vec![]);
sleep(Duration::from_millis(200)).await;
let users = store.select(|state: &UserState| state.users.clone()).await;
assert_eq!(
users,
vec![
User {
id: 0,
name: "John Doe".to_string(),
},
User {
id: 1,
name: "Jane Doe".to_string(),
},
]
);
Trait Implementations
sourceimpl<State, Action, Inner> MiddleWare<State, ActionOrThunk<State, Action, Inner>, Inner, Action> for ThunkMiddleware where
Action: Send + 'static,
State: Send + 'static,
Inner: StoreApi<State, Action> + Send + Sync + 'static,
impl<State, Action, Inner> MiddleWare<State, ActionOrThunk<State, Action, Inner>, Inner, Action> for ThunkMiddleware where
Action: Send + 'static,
State: Send + 'static,
Inner: StoreApi<State, Action> + Send + Sync + 'static,
sourcefn dispatch<'life0, 'life1, 'async_trait>(
&'life0 self,
action: ActionOrThunk<State, Action, Inner>,
inner: &'life1 Arc<Inner>
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn dispatch<'life0, 'life1, 'async_trait>(
&'life0 self,
action: ActionOrThunk<State, Action, Inner>,
inner: &'life1 Arc<Inner>
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
This method is called every time an action is dispatched to the store. Read more
sourcefn 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,
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,
This method is called the moment the middleware is wrapped around an underlying store api. Initialization could be done here. Read more
Auto Trait Implementations
impl RefUnwindSafe for ThunkMiddleware
impl Send for ThunkMiddleware
impl Sync for ThunkMiddleware
impl Unpin for ThunkMiddleware
impl UnwindSafe for ThunkMiddleware
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more