Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DioxusLabs/dioxus/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Scopes represent individual component instances in the virtual DOM tree. Each component has its own scope that provides context, state management, and lifecycle control.
ScopeId
A unique identifier for a component scope.
pub struct ScopeId(pub usize);
Constants
The ID of the user’s root scope. This scope lasts for the entire app lifetime, making it convenient for long-lived state.// Create a signal in the app scope
let global_state = Signal::new_in_scope(
String::new(),
ScopeId::APP
);
The ID of the topmost scope in the tree. This is higher than APP because Dioxus inserts default error and suspense boundaries.
ScopeId::ROOT_ERROR_BOUNDARY
The ID of the topmost error boundary in the tree.
ScopeId::ROOT_SUSPENSE_BOUNDARY
The ID of the topmost suspense boundary in the tree.
Example Usage
use dioxus::prelude::*;
#[component]
fn MyComponent() -> Element {
// Get the current scope ID
let scope_id = current_scope_id().unwrap();
// Create state in a specific scope
let app_state = Signal::new_in_scope(0, ScopeId::APP);
rsx! {
div { "Scope ID: {scope_id:?}" }
}
}
ScopeState
Represents a component’s rendered state and provides access to the component’s runtime context.
pub struct ScopeState {
runtime: Rc<Runtime>,
context_id: ScopeId,
last_rendered_node: Option<LastRenderedNode>,
props: BoxedAnyProps,
reactive_context: ReactiveContext,
}
Methods
root_node()
Gets the currently active root node for this scope.
pub fn root_node(&self) -> &VNode
Panics if the tree hasn’t been built yet.
let scope = dom.get_scope(scope_id).unwrap();
let node = scope.root_node();
try_root_node()
Tries to get the root node, returning None if not built yet.
pub fn try_root_node(&self) -> Option<&VNode>
if let Some(node) = scope.try_root_node() {
// Process node
}
id()
Returns the scope’s ID.
pub fn id(&self) -> ScopeId
let scope = dom.get_scope(scope_id).unwrap();
let id = scope.id();
height()
Returns the scope’s height in the component tree.
pub fn height(&self) -> u32
The root scope has height 0, its children have height 1, etc.
let height = scope.height();
println!("Scope depth: {}", height);
Context API
Scopes provide context for sharing state down the component tree without prop drilling.
Providing Context
use dioxus::prelude::*;
#[derive(Clone)]
struct Theme {
primary_color: String,
font_size: u32,
}
#[component]
fn App() -> Element {
// Provide context for child components
provide_context(Theme {
primary_color: "#007bff".to_string(),
font_size: 16,
});
rsx! {
ThemedButton { text: "Click me" }
}
}
Consuming Context
#[component]
fn ThemedButton(text: String) -> Element {
// Consume context from parent
let theme = consume_context::<Theme>();
rsx! {
button {
style: "color: {theme.primary_color}; font-size: {theme.font_size}px",
"{text}"
}
}
}
Context Functions
Provides a context value to child components.pub fn provide_context<T: Clone + 'static>(value: T)
Consumes a context value from parent components. Panics if not found.pub fn consume_context<T: Clone + 'static>() -> T
Tries to consume a context value, returning None if not found.pub fn try_consume_context<T: Clone + 'static>() -> Option<T>
Checks if a context value exists in parent scopes.pub fn has_context<T: 'static>() -> bool
Scope Utilities
Getting Current Scope
use dioxus::prelude::*;
#[component]
fn MyComponent() -> Element {
let scope_id = current_scope_id().unwrap();
rsx! {
div { "Current scope: {scope_id:?}" }
}
}
Parent Scope
use dioxus::prelude::*;
#[component]
fn ChildComponent() -> Element {
let parent = parent_scope();
rsx! {
div { "Parent scope: {parent:?}" }
}
}
Owner Context
use dioxus::prelude::*;
#[component]
fn MyComponent() -> Element {
let owner = current_owner();
// Run code in a specific owner context
with_owner(owner, || {
// This code runs with the owner context
});
rsx! { div { "Hello" } }
}
Scheduling Updates
Manual Re-renders
use dioxus::prelude::*;
#[component]
fn MyComponent() -> Element {
// Schedule this component to re-render
schedule_update();
rsx! { div { "Will re-render" } }
}
Schedule Any Scope
// Schedule a specific scope to re-render
schedule_update_any(scope_id);
Lifecycle Hooks
Before Render
use dioxus::prelude::*;
#[component]
fn MyComponent() -> Element {
use_before_render(move || {
println!("About to render");
});
rsx! { div { "Hello" } }
}
After Render
#[component]
fn MyComponent() -> Element {
use_after_render(move || {
println!("Finished rendering");
});
rsx! { div { "Hello" } }
}
On Drop
#[component]
fn MyComponent() -> Element {
use_drop(move || {
println!("Component unmounting");
});
rsx! { div { "Hello" } }
}
Reactive Context
The reactive context tracks signal subscriptions for automatic re-renders.
#[component]
fn Counter() -> Element {
let mut count = use_signal(|| 0);
// Reading count subscribes this scope to updates
let current = count();
rsx! {
div {
p { "Count: {current}" }
button {
// Writing to count triggers re-render
onclick: move |_| count += 1,
"Increment"
}
}
}
}
Scope Hierarchy
// Root Scope (ScopeId::ROOT)
// ├─ Suspense Boundary (ScopeId::ROOT_SUSPENSE_BOUNDARY)
// │ └─ Error Boundary (ScopeId::ROOT_ERROR_BOUNDARY)
// │ └─ App Component (ScopeId::APP)
// │ ├─ Child Component (ScopeId(4))
// │ └─ Child Component (ScopeId(5))
Traversing the Tree
use dioxus::prelude::*;
fn print_scope_tree(dom: &VirtualDom, scope_id: ScopeId, depth: usize) {
let scope = dom.get_scope(scope_id).unwrap();
let indent = " ".repeat(depth);
println!("{}{:?} (height: {})", indent, scope_id, scope.height());
}
Advanced Usage
Custom Scope Storage
use dioxus::prelude::*;
#[derive(Clone)]
struct ScopeData {
created_at: std::time::Instant,
}
#[component]
fn MyComponent() -> Element {
// Store custom data in scope context
provide_context(ScopeData {
created_at: std::time::Instant::now(),
});
rsx! { div { "Component initialized" } }
}
Accessing VirtualDom from Scope
// In custom renderers or advanced use cases
let scope = dom.get_scope(scope_id).unwrap();
let root_node = scope.root_node();
// Traverse the rendered tree
for root in &root_node.template.roots {
// Process template nodes
}
See Also