pub struct StateContext<'c, 'a, S: State> { /* private fields */ }Expand description
What a State is told when it builds and when its lifecycle runs: everything a
BuildContext offers (this dereferences to one), and the state’s own handle.
Implementations§
Source§impl<S: State> StateContext<'_, '_, S>
impl<S: State> StateContext<'_, '_, S>
Sourcepub fn handle(&self) -> StateHandle<S>
pub fn handle(&self) -> StateHandle<S>
A handle to this state that a handler, a listener or a timer can own.
Methods from Deref<Target = BuildContext<'a>>§
Sourcepub fn use_future<D, F>(
&self,
deps: D,
make: impl FnOnce() -> F,
) -> AsyncSnapshot<F::Output>
pub fn use_future<D, F>( &self, deps: D, make: impl FnOnce() -> F, ) -> AsyncSnapshot<F::Output>
Runs the future make() returns, once until deps change, and gives what is known
of it: waiting, then done with its value. A rebuild in between does not start it again.
Natively the future runs on the shell’s executor, so it must be Send; on the Web the
browser runs it. A value that arrives rebuilds the tree at the next frame. When deps
change, a new future starts, and what the old one gives is not shown.
use frus_widgets::{component, text, ConnectionState};
let answer = component(|cx| {
let snapshot = cx.use_future((), || async { 6 * 7 });
Box::new(match snapshot.data {
Some(value) => text(format!("{value}")),
None => text("Working it out…"),
})
});Sourcepub fn use_stream<D, T, F>(
&self,
deps: D,
make: impl FnOnce(StreamSink<T>) -> F,
) -> AsyncSnapshot<T>
pub fn use_stream<D, T, F>( &self, deps: D, make: impl FnOnce(StreamSink<T>) -> F, ) -> AsyncSnapshot<T>
Runs the work make returns, once until deps change, handing it a
StreamSink to give its values to, and gives what is known of it: waiting, active
with the latest value, then done with the last one.
The reference builds this on a stream type; here the stream is the work itself, giving its values as it goes, which asks for no stream library.
use frus_widgets::{component, text};
let countdown = component(|cx| {
let snapshot = cx.use_stream((), |sink| async move {
for left in (0..3).rev() {
sink.add(left);
}
});
Box::new(text(format!("{:?}", snapshot.data)))
});Sourcepub fn service<T: 'static>(&self) -> Option<Rc<T>>
pub fn service<T: 'static>(&self) -> Option<Rc<T>>
An application-wide object provided with StateStore::provide — a router, say.
Sourcepub fn use_state<T: 'static>(&self, init: impl FnOnce() -> T) -> UseState<T>
pub fn use_state<T: 'static>(&self, init: impl FnOnce() -> T) -> UseState<T>
A value that lives as long as this component does, and that asks for a rebuild when
it changes. init makes it the first time and is not called again.
fn label(cx: &BuildContext) -> Box<dyn Widget> {
let taps = cx.use_state(|| 0);
taps.set(taps.get() + 1);
Box::new(text(format!("{}", taps.get())))
}Sourcepub fn use_ref<T: 'static>(&self, init: impl FnOnce() -> T) -> UseRef<T>
pub fn use_ref<T: 'static>(&self, init: impl FnOnce() -> T) -> UseRef<T>
A value that lives as long as this component does and does not ask for a rebuild when it changes.
Sourcepub fn use_memo<D: PartialEq + 'static, T: 'static>(
&self,
deps: D,
compute: impl FnOnce() -> T,
) -> Rc<T>
pub fn use_memo<D: PartialEq + 'static, T: 'static>( &self, deps: D, compute: impl FnOnce() -> T, ) -> Rc<T>
compute(), kept until deps change. The work is not repeated on a rebuild that
changes nothing it depends on.
Sourcepub fn use_interval(&self, period: Duration, on_tick: impl Into<Callback>)
pub fn use_interval(&self, period: Duration, on_tick: impl Into<Callback>)
Calls on_tick every period, for as long as this component asks for it.
It asks again on every build: a build that does not call this any more stops the timer,
and a build that calls it with another period starts a new one. So, unlike the other
hooks, it may be called conditionally — a timer that is only wanted while something is on
is if on { cx.use_interval(..) }.
on_tick runs on the interface’s thread, like any other handler, so it may change
state: cx.use_interval(period, cx.callback(|state| state.seconds += 1)).
fn clock(cx: &BuildContext) -> Box<dyn Widget> {
let seconds = cx.use_state(|| 0);
let tick = seconds.clone();
cx.use_interval(Duration::from_secs(1), move || tick.update(|s| *s += 1));
Box::new(text(format!("{}s", seconds.get())))
}Sourcepub fn block_back(&self, blocked: bool)
pub fn block_back(&self, blocked: bool)
Says, for this build, whether something this component shows — a menu, a dialog, a
drawer — should take the back gesture and the back button before the router does.
While any component says true, the router is not asked to go back.
Like use_interval it is asked again on every build and may be
called conditionally: cx.block_back(self.menu_open).
Sourcepub fn use_effect<D, C>(&self, deps: D, effect: impl FnOnce() -> C + 'static)where
D: PartialEq + 'static,
C: IntoCleanup,
pub fn use_effect<D, C>(&self, deps: D, effect: impl FnOnce() -> C + 'static)where
D: PartialEq + 'static,
C: IntoCleanup,
Work to do after the tree is built — start a timer, subscribe, read a controller —
run again whenever deps change, not otherwise. Pass () to run it once.
The work may return a closure, which undoes it: it runs before the next run and when the component leaves the tree.
fn title(cx: &BuildContext) -> Box<dyn Widget> {
cx.use_effect((), || {
println!("mounted");
|| println!("unmounted")
});
Box::new(text("hello"))
}Sourcepub fn use_text_controller(&self, initial: &str) -> TextEditingController
pub fn use_text_controller(&self, initial: &str) -> TextEditingController
A TextEditingController that lives as long as this component does, holding
initial to begin with. The same controller comes back on every rebuild.