Expand description
This library is inspired by redux, and designed to be used within Rust GUI applications to manage centralised global state which behaves in a predictable way.
§Example
The following is a simple example of how to use this system to manage state, and subscribe to changes to state.
use reactive_state::{ReducerFn, ReducerResult, Store, Callback};
use std::{cell::RefCell, rc::Rc};
/// Something to hold the application state.
#[derive(Clone)]
struct MyState {
pub variable: u32
}
/// Some actions to perform which alter the state.
enum MyAction {
Increment,
Decrement
}
/// Some events that are fired during certain action/state combinations.
#[derive(Clone, Eq, PartialEq, Hash)]
enum MyEvent {
IsOne,
}
/// A reducer to perform the actions, alter the state, and fire off events.
let reducer: ReducerFn<MyState, MyAction, MyEvent, ()> = |state, action| {
let mut events: Vec<MyEvent> = Vec::new();
let new_state = match action {
MyAction::Increment => {
let mut new_state = MyState::clone(state);
new_state.variable = state.variable + 1;
Rc::new(new_state)
}
MyAction::Decrement => {
let mut new_state = MyState::clone(state);
new_state.variable = state.variable - 1;
Rc::new(new_state)
}
};
if new_state.variable == 1 {
events.push(MyEvent::IsOne);
}
ReducerResult {
state: new_state,
events,
effects: vec![],
}
};
// Set the initial state.
let initial_state = MyState {
variable: 0u32
};
// Create the store.
let store = Store::new(reducer, initial_state);
// A test variable that will be altered by the callback.
let callback_invokes: Rc<RefCell<u32>> = Rc::new(RefCell::new(0u32));
let callback_invokes_local = callback_invokes.clone();
let callback = Callback::new(move |_state: Rc<MyState>, _event: Option<MyEvent>| {
*(callback_invokes_local.borrow_mut()) += 1;
});
// Subscribe to state changes which produce the IsOne event.
store.subscribe_event(&callback, MyEvent::IsOne);
assert_eq!(0, store.state().variable);
assert_eq!(0, *RefCell::borrow(&callback_invokes));
// Dispatch an increment action onto the store, which will
// alter the state.
store.dispatch(MyAction::Increment);
// The state has been altered.
assert_eq!(1, store.state().variable);
// The callback was invoked.
assert_eq!(1, *RefCell::borrow(&callback_invokes));
store.dispatch(MyAction::Increment);
// The state has been altered.
assert_eq!(2, store.state().variable);
// The callback was not invoked, because the event IsOne
// was not fired by the reducer.
assert_eq!(1, *RefCell::borrow(&callback_invokes));
// Drop the callback, and it will also be removed from the store.
drop(callback);
store.dispatch(MyAction::Decrement);
// The state has been altered again.
assert_eq!(1, store.state().variable);
// The callback was dropped before the action was dispatched,
// and so it was not invoked.
assert_eq!(1, *RefCell::borrow(&callback_invokes));
§Side Effects
Something that wasn’t covered in the example above, was the
concept of side effects produced in the reducer. This is the
fourth type parameter Effect
on Store, and effects
which are produced in the reducer are given to the store via the
ReducerResult that it returns. Side effects are
designed to be executed/handled by store middleware.
§Optional Features
The following optional crate features can be enabled:
"simple_logger"
- Logging middleware in the simple_logger module which uses thelog
macros."web_logger"
- Logging middleware in the web_logger module, for applications running in the browser using wasm-bindgen."yew"
- Support for compatibility trait implementations on yew types.
Modules§
- Middleware used to modify the behaviour of a Store during a Store::dispatch(). This module also contains some simple middleware implementations which can be used as utilities in an application.
- provider
yew
Structs§
- A wrapper for a callback which is notified of changes to Store
State
, andEvent
s produced by the store. - A Reducer composed of multiple reducers.
- The result of a Reducer::reduce() function.
- This struct is designed to operate as a central source of truth and global “immutable” state within your application.
Traits§
- Using the reduce() method, implementors of this trait take an
Action
submitted to a store via Store::dispatch() and modifies theState
in the store, producing a newState
, and also producing events and effects associated with theAction
and state modifications that occurred.
Type Aliases§
- A wrapper for a function that implements the Reducer trait.