mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 12:43:08 +00:00
feat: allow providing context to the root component
This commit is contained in:
parent
8d3ac3ff14
commit
d2bd175143
1 changed files with 50 additions and 0 deletions
|
@ -667,6 +667,56 @@ impl ScopeState {
|
|||
value
|
||||
}
|
||||
|
||||
/// Provide a context for the root component from anywhere in your app.
|
||||
///
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust, ignore
|
||||
/// struct SharedState(&'static str);
|
||||
///
|
||||
/// static App: Component = |cx| {
|
||||
/// cx.use_hook(|_| cx.provide_root_context(SharedState("world")));
|
||||
/// rsx!(cx, Child {})
|
||||
/// }
|
||||
///
|
||||
/// static Child: Component = |cx| {
|
||||
/// let state = cx.consume_state::<SharedState>();
|
||||
/// rsx!(cx, div { "hello {state.0}" })
|
||||
/// }
|
||||
/// ```
|
||||
pub fn provide_root_context<T: 'static>(&self, value: T) -> Rc<T> {
|
||||
let value = Rc::new(value);
|
||||
|
||||
// if we *are* the root component, then we can just provide the context directly
|
||||
if self.scope_id() == ScopeId(0) {
|
||||
self.shared_contexts
|
||||
.borrow_mut()
|
||||
.insert(TypeId::of::<T>(), value.clone())
|
||||
.map(|f| f.downcast::<T>().ok())
|
||||
.flatten();
|
||||
}
|
||||
|
||||
let mut search_parent = self.parent_scope;
|
||||
|
||||
while let Some(parent) = search_parent.take() {
|
||||
let parent = unsafe { &*parent };
|
||||
|
||||
if parent
|
||||
.shared_contexts
|
||||
.borrow_mut()
|
||||
.insert(TypeId::of::<T>(), value.clone())
|
||||
.is_some()
|
||||
{
|
||||
log::warn!("Context already provided to parent scope - replacing it");
|
||||
}
|
||||
|
||||
search_parent = parent.parent_scope;
|
||||
}
|
||||
|
||||
value
|
||||
}
|
||||
|
||||
/// Try to retrieve a SharedState with type T from the any parent Scope.
|
||||
pub fn consume_context<T: 'static>(&self) -> Option<Rc<T>> {
|
||||
if let Some(shared) = self.shared_contexts.borrow().get(&TypeId::of::<T>()) {
|
||||
|
|
Loading…
Reference in a new issue