How to store state globally in Yew.
Installing Yewdux
Yewdux is react equivelent to Redux for Yew projects.
cargo add yewdux
Creating global state.
use yewdux::store::Store;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Todo {
pub id: i32,
pub title: String,
pub completed: bool,
}
Use this state in your components.
How to update the state in use_effect?
let (todo_state, dispatch) = use_store::<TodoState>();
use_effect_with_deps(
move |_| {
let dispatch = use_effect_dispatch.clone();
let todos = local_storage::get_todos_from_localstorage();
dispatch.clone().set(TodoState { todos });
},
(),
);
Creating callbacks from the dispatch.
let create_todo = dispatch.reduce_mut_callback(move |todo_state| {
let now = js_sys::Date::get_milliseconds(&js_sys::Date::new_0()) as i32;
let todo = Todo {
id: now,
title: value.clone().to_string(),
completed: false,
};
todo_state.todos = todo_state
.todos
.iter()
.cloned()
.chain(Some(todo.clone()))
.collect();
local_storage::insert_todo_to_localstorage(todo.clone()).unwrap();
value.set(String::from(""));
});
An example to use the state.
...
{for todo_state.todos.iter().map(|todo| {
html! {
<li style={"margin-bottom: 0.3rem"}>
<button onclick={on_todo_delete}>{"🗑️"}</button>
<button onclick={on_todo_update}>{"✏️"}</button>
<input type="checkbox" checked={todo.completed} onchange={on_todo_select}/>
<span style={"margin-right: 1rem;"}>
{&todo.title}
</span>
</li>
}
})}
...