yew/functional/hooks/
use_state.rs1use std::fmt;
2use std::ops::Deref;
3use std::rc::Rc;
4
5use super::{use_reducer, use_reducer_eq, Reducible, UseReducerDispatcher, UseReducerHandle};
6use crate::functional::hook;
7use crate::html::IntoPropValue;
8use crate::Callback;
9
10struct UseStateReducer<T> {
11 value: T,
12}
13
14impl<T> Reducible for UseStateReducer<T> {
15 type Action = T;
16
17 fn reduce(self: Rc<Self>, action: Self::Action) -> Rc<Self> {
18 Rc::new(Self { value: action })
19 }
20}
21
22impl<T> PartialEq for UseStateReducer<T>
23where
24 T: PartialEq,
25{
26 fn eq(&self, rhs: &Self) -> bool {
27 self.value == rhs.value
28 }
29}
30
31#[hook]
78pub fn use_state<T, F>(init_fn: F) -> UseStateHandle<T>
79where
80 T: 'static,
81 F: FnOnce() -> T,
82{
83 let handle = use_reducer(move || UseStateReducer { value: init_fn() });
84
85 UseStateHandle { inner: handle }
86}
87
88#[hook]
92pub fn use_state_eq<T, F>(init_fn: F) -> UseStateHandle<T>
93where
94 T: PartialEq + 'static,
95 F: FnOnce() -> T,
96{
97 let handle = use_reducer_eq(move || UseStateReducer { value: init_fn() });
98
99 UseStateHandle { inner: handle }
100}
101
102pub struct UseStateHandle<T> {
104 inner: UseReducerHandle<UseStateReducer<T>>,
105}
106
107impl<T: fmt::Debug> fmt::Debug for UseStateHandle<T> {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 f.debug_struct("UseStateHandle")
110 .field("value", &format!("{:?}", self.inner.value))
111 .finish()
112 }
113}
114
115impl<T> UseStateHandle<T> {
116 pub fn set(&self, value: T) {
118 self.inner.dispatch(value)
119 }
120
121 pub fn setter(&self) -> UseStateSetter<T> {
123 UseStateSetter {
124 inner: self.inner.dispatcher(),
125 }
126 }
127}
128
129impl<T> Deref for UseStateHandle<T> {
130 type Target = T;
131
132 fn deref(&self) -> &Self::Target {
133 &(*self.inner).value
134 }
135}
136
137impl<T> Clone for UseStateHandle<T> {
138 fn clone(&self) -> Self {
139 Self {
140 inner: self.inner.clone(),
141 }
142 }
143}
144
145impl<T> PartialEq for UseStateHandle<T>
146where
147 T: PartialEq,
148{
149 fn eq(&self, rhs: &Self) -> bool {
150 *self.inner == *rhs.inner
151 }
152}
153
154pub struct UseStateSetter<T> {
156 inner: UseReducerDispatcher<UseStateReducer<T>>,
157}
158
159impl<T> Clone for UseStateSetter<T> {
160 fn clone(&self) -> Self {
161 Self {
162 inner: self.inner.clone(),
163 }
164 }
165}
166
167impl<T> fmt::Debug for UseStateSetter<T>
168where
169 T: fmt::Debug,
170{
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 f.debug_struct("UseStateSetter").finish()
173 }
174}
175
176impl<T> From<UseStateSetter<T>> for Callback<T> {
177 fn from(value: UseStateSetter<T>) -> Self {
178 Self::from(value.inner)
179 }
180}
181
182impl<T> IntoPropValue<Callback<T>> for UseStateSetter<T> {
183 fn into_prop_value(self) -> Callback<T> {
184 self.inner.into_prop_value()
185 }
186}
187
188impl<T> PartialEq for UseStateSetter<T> {
189 fn eq(&self, rhs: &Self) -> bool {
190 self.inner == rhs.inner
191 }
192}
193
194impl<T> UseStateSetter<T> {
195 pub fn set(&self, value: T) {
197 self.inner.dispatch(value)
198 }
199
200 pub fn to_callback(&self) -> Callback<T> {
203 self.inner.to_callback()
204 }
205}