forked from redux-rs/redux-rs
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy paththunk_middleware_fn.rs
76 lines (66 loc) · 1.98 KB
/
thunk_middleware_fn.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use redux_rs::middlewares::thunk::{ActionOrThunk, ThunkMiddleware};
use redux_rs::{Store, StoreApi};
use std::sync::Arc;
use std::time::Duration;
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;
}
#[tokio::main]
async fn main() {
// Set up the store with a reducer and wrap it with thunk middleware
// Because the store is now wrapped with ThunkMiddleware we need to dispatch ActionOrThunk instead of actions
let store = Store::new(user_reducer).wrap(ThunkMiddleware).await;
// Dispatch our thunk which emulates loading users from an api
store.dispatch(ActionOrThunk::Thunk(Box::new(load_users))).await;
// Wait till the "api call" is completed
sleep(Duration::from_millis(200)).await;
// Get the users from the store
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(),
},
]
);
}