Skip to main content

BuildContext

Struct BuildContext 

Source
pub struct BuildContext<'a> { /* private fields */ }
Expand description

What a component is told when it is built: where it is, under which theme, and where its hooks keep their values.

Implementations§

Source§

impl<'a> BuildContext<'a>

Source

pub fn use_future<D, F>( &self, deps: D, make: impl FnOnce() -> F, ) -> AsyncSnapshot<F::Output>
where D: PartialEq + 'static, F: Future + MaybeSend + 'static, F::Output: Clone + MaybeSend + 'static,

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…"),
    })
});
Source

pub fn use_stream<D, T, F>( &self, deps: D, make: impl FnOnce(StreamSink<T>) -> F, ) -> AsyncSnapshot<T>
where D: PartialEq + 'static, T: Clone + MaybeSend + 'static, F: Future<Output = ()> + MaybeSend + 'static,

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)))
});
Source§

impl<'a> BuildContext<'a>

Source

pub fn theme(&self) -> &Theme

The theme this component is built under.

Source

pub fn id(&self) -> WidgetId

Where in the tree this component sits.

Source

pub fn runtime(&self) -> &Runtime

The runtime the tree is being built for.

Source

pub fn service<T: 'static>(&self) -> Option<Rc<T>>

An application-wide object provided with StateStore::provide — a router, say.

Source

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())))
}
Source

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.

Source

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.

Source

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())))
}
Source

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).

Source

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"))
}
Source§

impl BuildContext<'_>

Source

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.

Source§

impl BuildContext<'_>

Source

pub fn router(&self) -> GoRouter

The application’s router. Handlers capture it and navigate from there:

ⓘ
let router = cx.router();
button("Open", move || router.go("/settings"))

Panics if this application has no router — one made with FrusApp::router.

Auto Trait Implementations§

§

impl<'a> !Freeze for BuildContext<'a>

§

impl<'a> !RefUnwindSafe for BuildContext<'a>

§

impl<'a> !Send for BuildContext<'a>

§

impl<'a> !Sync for BuildContext<'a>

§

impl<'a> !UnwindSafe for BuildContext<'a>

§

impl<'a> Unpin for BuildContext<'a>

§

impl<'a> UnsafeUnpin for BuildContext<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<Msg> IntoMsg<Msg> for Msg

Source§

fn defer(work: impl Fn() -> Msg + 'static) -> Msg

The message that stands for work’s result.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.