Struct dioxus_core::context::Context[][src]

pub struct Context<'src> {
    pub scope: &'src Scope,
}
Expand description

Components in Dioxus use the “Context” object to interact with their lifecycle.

This lets components access props, schedule updates, integrate hooks, and expose shared state.

Note: all of these methods are imperative - they do not act as hooks! They are meant to be used by hooks to provide complex behavior. For instance, calling “add_shared_state” on every render is considered a leak. This method exists for the use_provide_state hook to provide a shared state object.

For the most part, the only method you should be using regularly is render.

Example

#[derive(Properties)]
struct Props {
    name: String
}

fn example(cx: Context<Props>) -> VNode {
    html! {
        <div> "Hello, {cx.name}" </div>
    }
}

Fields

scope: &'src Scope

Implementations

Access the children elements passed into the component

This enables patterns where a component is passed children from its parent.

Details

Unlike React, Dioxus allows only lists of children to be passed from parent to child - not arbitrary functions or classes. If you want to generate nodes instead of accepting them as a list, consider declaring a closure on the props that takes Context.

If a parent passes children into a component, the child will always re-render when the parent re-renders. In other words, a component cannot be automatically memoized if it borrows nodes from its parent, even if the component’s props are valid for the static lifetime.

Example

const App: FC<()> = |cx, props|{
    cx.render(rsx!{
        CustomCard {
            h1 {}
            p {}
        }
    })
}

const CustomCard: FC<()> = |cx, props|{
    cx.render(rsx!{
        div {
            h1 {"Title card"}
            {cx.children()}
        }
    })
}

Notes:

This method returns a “ScopeChildren” object. This object is copy-able and preserve the correct lifetime.

Create a subscription that schedules a future render for the reference component

Notice: you should prefer using prepare_update and get_scope_id

Schedule an update for any component given its ScopeId.

A component’s ScopeId can be obtained from use_hook or the Context::scope_id method.

This method should be used when you want to schedule an update for a component

Get the ScopeId of a mounted component.

ScopeId is not unique for the lifetime of the VirtualDom - a ScopeId will be reused if a component is unmounted.

Take a lazy VNode structure and actually build it with the context of the VDom’s efficient VNode allocator.

This function consumes the context and absorb the lifetime, so these VNodes must be returned.

Example

fn Component(cx: Context<()>) -> VNode {
    // Lazy assemble the VNode tree
    let lazy_tree = html! {<div> "Hello World" </div>};
    
    // Actually build the tree and allocate it
    cx.render(lazy_tree)
}

submit_task will submit the future to be polled.

This is useful when you have some async task that needs to be progressed.

This method takes ownership over the task you’ve provided, and must return (). This means any work that needs to happen must occur within the future or scheduled for after the future completes (through schedule_update )

Explanation

Dioxus will step its internal event loop if the future returns if the future completes while waiting.

Tasks can’t return anything, but they can be controlled with the returned handle

Tasks will only run until the component renders again. Because submit_task is valid for the &’src lifetime, it is considered “stable”

This hook enables the ability to expose state to children further down the VirtualDOM Tree.

This is a hook, so it should not be called conditionally!

The init method is ran only on first use, otherwise it is ignored. However, it uses hooks (ie use) so don’t put it in a conditional.

When the component is dropped, so is the context. Be aware of this behavior when consuming the context via Rc/Weak.

Example

struct SharedState(&'static str);

static App: FC<()> = |cx, props|{
    cx.use_provide_state(|| SharedState("world"));
    rsx!(cx, Child {})
}

static Child: FC<()> = |cx, props|{
    let state = cx.use_consume_state::<SharedState>();
    rsx!(cx, div { "hello {state.0}" })
}

Uses a context, storing the cached value around

If a context is not found on the first search, then this call will be “dud”, always returning “None” even if a context was added later. This allows using another hook as a fallback

Store a value between renders

This is the foundational hook for all other hooks.

  • Initializer: closure used to create the initial hook state
  • Runner: closure used to output a value every time the hook is used
  • Cleanup: closure used to teardown the hook once the dom is cleaned up

Example

// use_ref is the simplest way of storing a value between renders
fn use_ref<T: 'static>(initial_value: impl FnOnce() -> T) -> &RefCell<T> {
    use_hook(
        || Rc::new(RefCell::new(initial_value())),
        |state| state,
        |_| {},
    )
}

Methods from Deref<Target = &'a Scope>

Get the root VNode for this Scope.

This VNode is the “entrypoint” VNode. If the component renders multiple nodes, then this VNode will be a fragment.

Example

let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
dom.rebuild();

let base = dom.base_scope();

if let VNode::VElement(node) = base.root_node() {
    assert_eq!(node.tag_name, "div");
}

Get the height of this Scope - IE the number of scopes above it.

A Scope with a height of 0 is the root scope - there are no other scopes above it.

Example

let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
dom.rebuild();

let base = dom.base_scope();

assert_eq!(base.height(), 0);

Get the Parent of this Scope within this Dioxus VirtualDOM.

This ID is not unique across Dioxus VirtualDOMs or across time. IDs will be reused when components are unmounted.

The base component will not have a parent, and will return None.

Example

let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
dom.rebuild();

let base = dom.base_scope();

assert_eq!(base.parent(), None);

Get the ID of this Scope within this Dioxus VirtualDOM.

This ID is not unique across Dioxus VirtualDOMs or across time. IDs will be reused when components are unmounted.

Example

let mut dom = VirtualDom::new(|cx, props|cx.render(rsx!{ div {} }));
dom.rebuild();
let base = dom.base_scope();

assert_eq!(base.scope_id(), 0);

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

The resulting type after dereferencing.

Dereferences the value.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.