added better documentation and code snipppets for the use_resource, use_future, use_effect and use_context hooks
This commit is contained in:
1 parent
451a8f231e
commit
df0d45be48
8 files changed
+99
-7
No files matched your search
@@ -14,6 +14,18 @@ pub fn try_use_context<T: 'static + Clone>() -> Option<T> {
|
|||||||
/// Consume some context in the tree, providing a sharable handle to the value
|
/// Consume some context in the tree, providing a sharable handle to the value
|
||||||
///
|
///
|
||||||
/// Does not regenerate the value if the value is changed at the parent.
|
/// Does not regenerate the value if the value is changed at the parent.
|
||||||
|
/// ```rust
|
||||||
|
/// fn Parent() -> Element {
|
||||||
|
/// use_context_provider(|| Theme::Dark);
|
||||||
|
/// rsx! { Child {} }
|
||||||
|
/// }
|
||||||
|
/// #[component]
|
||||||
|
/// fn Child() -> Element {
|
||||||
|
/// //gets context provided by parent element with use_context_provider
|
||||||
|
/// let user_theme = use_context::<Theme>();
|
||||||
|
/// rsx! { "user using dark mode: {user_theme == Theme::Dark}" }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn use_context<T: 'static + Clone>() -> T {
|
pub fn use_context<T: 'static + Clone>() -> T {
|
||||||
use_hook(|| consume_context::<T>())
|
use_hook(|| consume_context::<T>())
|
||||||
@@ -22,6 +34,21 @@ pub fn use_context<T: 'static + Clone>() -> T {
|
|||||||
/// Provide some context via the tree and return a reference to it
|
/// Provide some context via the tree and return a reference to it
|
||||||
///
|
///
|
||||||
/// Once the context has been provided, it is immutable. Mutations should be done via interior mutability.
|
/// Once the context has been provided, it is immutable. Mutations should be done via interior mutability.
|
||||||
|
/// Context can be read by any child components of the context provider, and is a solution to prop
|
||||||
|
/// drilling, using a context provider with a Signal inside is a good way to provide global/shared
|
||||||
|
/// state in your app:
|
||||||
|
/// ```rust
|
||||||
|
///fn app() -> Element {
|
||||||
|
/// use_context_provider(|| Signal::new(0));
|
||||||
|
/// rsx! { Child {} }
|
||||||
|
///}
|
||||||
|
// This component does read from the signal, so when the signal changes it will rerun
|
||||||
|
///#[component]
|
||||||
|
///fn Child() -> Element {
|
||||||
|
/// let signal: Signal<i32> = use_context();
|
||||||
|
/// rsx! { "{signal}" }
|
||||||
|
///}
|
||||||
|
/// ```
|
||||||
pub fn use_context_provider<T: 'static + Clone>(f: impl FnOnce() -> T) -> T {
|
pub fn use_context_provider<T: 'static + Clone>(f: impl FnOnce() -> T) -> T {
|
||||||
use_hook(|| {
|
use_hook(|| {
|
||||||
let val = f();
|
let val = f();
|
||||||
|
|||||||
@@ -93,7 +93,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a handle to a coroutine higher in the tree
|
/// Get a handle to a coroutine higher in the tree
|
||||||
///
|
/// Analagous to use_context_provider and use_context,
|
||||||
|
/// but used for coroutines specifically
|
||||||
/// See the docs for [`use_coroutine`] for more details.
|
/// See the docs for [`use_coroutine`] for more details.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn use_coroutine_handle<M: 'static>() -> Coroutine<M> {
|
pub fn use_coroutine_handle<M: 'static>() -> Coroutine<M> {
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
use dioxus_core::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
use dioxus_signals::ReactiveContext;
|
use dioxus_signals::ReactiveContext;
|
||||||
|
|
||||||
/// Create a new effect. The effect will be run immediately and whenever any signal it reads changes.
|
/// use_effect will subscribe to any changes in the signal values it captures
|
||||||
/// The signal will be owned by the current component and will be dropped when the component is dropped.
|
/// effects will always run after first mount and then whenever the signal values change
|
||||||
///
|
|
||||||
/// If the use_effect call was skipped due to an early return, the effect will no longer activate.
|
/// If the use_effect call was skipped due to an early return, the effect will no longer activate.
|
||||||
|
/// ```rust
|
||||||
|
/// fn app() -> Element {
|
||||||
|
/// let mut count = use_signal(|| 0);
|
||||||
|
/// //the effect runs again each time count changes
|
||||||
|
/// use_effect(move || println!("Count changed to {count}"));
|
||||||
|
///
|
||||||
|
/// rsx! {
|
||||||
|
/// h1 { "High-Five counter: {count}" }
|
||||||
|
/// button { onclick: move |_| count += 1, "Up high!" }
|
||||||
|
/// button { onclick: move |_| count -= 1, "Down low!" }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn use_effect(mut callback: impl FnMut() + 'static) {
|
pub fn use_effect(mut callback: impl FnMut() + 'static) {
|
||||||
// let mut run_effect = use_hook(|| CopyValue::new(true));
|
// let mut run_effect = use_hook(|| CopyValue::new(true));
|
||||||
// use_hook_did_run(move |did_run| run_effect.set(did_run));
|
// use_hook_did_run(move |did_run| run_effect.set(did_run));
|
||||||
|
|||||||
@@ -12,6 +12,30 @@ use std::future::Future;
|
|||||||
///
|
///
|
||||||
/// The future is spawned on the next call to `flush_sync` which means that it will not run on the server.
|
/// The future is spawned on the next call to `flush_sync` which means that it will not run on the server.
|
||||||
/// To run a future on the server, you should use `spawn` directly.
|
/// To run a future on the server, you should use `spawn` directly.
|
||||||
|
/// use_future assumes your future will never complete - **it won't return a value**.
|
||||||
|
/// If you want to return a value, use `use_resource` instead.
|
||||||
|
/// ```rust
|
||||||
|
/// fn app() -> Element {
|
||||||
|
/// let mut count = use_signal(|| 0);
|
||||||
|
/// let mut running = use_signal(|| true);
|
||||||
|
/// // use_future will spawn an infinitely running future that can be started and stopped
|
||||||
|
/// use_future(move || async move {
|
||||||
|
/// loop {
|
||||||
|
/// if running() {
|
||||||
|
/// count += 1;
|
||||||
|
/// }
|
||||||
|
/// tokio::time::sleep(Duration::from_millis(400)).await;
|
||||||
|
/// }
|
||||||
|
/// });
|
||||||
|
/// rsx! {
|
||||||
|
/// div {
|
||||||
|
/// h1 { "Current count: {count}" }
|
||||||
|
/// button { onclick: move |_| running.toggle(), "Start/Stop the count"}
|
||||||
|
/// button { onclick: move |_| count.set(0), "Reset the count" }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub fn use_future<F>(mut future: impl FnMut() -> F + 'static) -> UseFuture
|
pub fn use_future<F>(mut future: impl FnMut() -> F + 'static) -> UseFuture
|
||||||
where
|
where
|
||||||
F: Future + 'static,
|
F: Future + 'static,
|
||||||
|
|||||||
@@ -10,8 +10,32 @@ use futures_util::{future, pin_mut, FutureExt};
|
|||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
/// A memo that resolve to a value asynchronously.
|
/// A memo that resolve to a value asynchronously.
|
||||||
|
/// Unlike `use_future`, `use_resource` runs on the **server**
|
||||||
|
/// See [`Resource`] for more details.
|
||||||
|
/// ```rust
|
||||||
|
///fn app() -> Element {
|
||||||
|
/// let country = use_signal(|| WeatherLocation {
|
||||||
|
/// city: "Berlin".to_string(),
|
||||||
|
/// country: "Germany".to_string(),
|
||||||
|
/// coordinates: (52.5244, 13.4105)
|
||||||
|
/// });
|
||||||
///
|
///
|
||||||
/// This runs on the server
|
/// let current_weather = //run a future inside the use_resource hook
|
||||||
|
/// use_resource(move || async move { get_weather(&country.read().clone()).await });
|
||||||
|
///
|
||||||
|
/// rsx! {
|
||||||
|
/// //the value of the future can be polled to
|
||||||
|
/// //conditionally render elements based off if the future
|
||||||
|
/// //finished (Some(Ok(_)), errored Some(Err(_)),
|
||||||
|
/// //or is still finishing (None)
|
||||||
|
/// match current_weather.value() {
|
||||||
|
/// Some(Ok(weather)) => WeatherElement { weather },
|
||||||
|
/// Some(Err(e)) => p { "Loading weather failed, {e}" }
|
||||||
|
/// None => p { "Loading..." }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///}
|
||||||
|
/// ```
|
||||||
#[must_use = "Consider using `cx.spawn` to run a future without reading its value"]
|
#[must_use = "Consider using `cx.spawn` to run a future without reading its value"]
|
||||||
pub fn use_resource<T, F>(future: impl Fn() -> F + 'static) -> Resource<T>
|
pub fn use_resource<T, F>(future: impl Fn() -> F + 'static) -> Resource<T>
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::write::Writable;
|
|||||||
use crate::{GlobalMemo, GlobalSignal, MappedSignal, ReadOnlySignal, SignalData};
|
use crate::{GlobalMemo, GlobalSignal, MappedSignal, ReadOnlySignal, SignalData};
|
||||||
use generational_box::{AnyStorage, Storage};
|
use generational_box::{AnyStorage, Storage};
|
||||||
|
|
||||||
|
use std::ops::Index;
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
ops::{Add, Div, Mul, Sub},
|
ops::{Add, Div, Mul, Sub},
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ use generational_box::{AnyStorage, Storage, SyncStorage, UnsyncStorage};
|
|||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut, Index, IndexMut},
|
||||||
sync::Mutex,
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a new Signal. Signals are a Copy state management solution with automatic dependency tracking.
|
/// Creates a new Signal. Signals are a Copy state management solution with automatic dependency tracking.
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#![allow(unused, non_upper_case_globals, non_snake_case)]
|
#![allow(unused, non_upper_case_globals, non_snake_case)]
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_core::ElementId;
|
use dioxus_core::ElementId;
|
||||||
use dioxus_core::NoOpMutations;
|
use dioxus_core::NoOpMutations;
|
||||||
|
|||||||
Reference in new issue
Block a user