pub struct Signal<T: SignalType, RT: Runtime> { /* private fields */ }
Expand description
A Signal is a reactive value or a function that produces a value, with subscribers that are automatically notified when the value changes.
When it is a function, the function automatically subscribes to all the other signals it is using and automatically re-runs when any of those signals change.
If the value implements PartialEq then the subscribers are notified only if the value changed.
A Signal is created in a reactive Scope using the signal! macro. It can only be deleted by discarding that Scope.
§Accessors
Only data signals can be manually changed. Func signals that only runs on server
or client
always return optional values which are some only when runninig on their side.
Value implements | Data signal | Func signal | Func signal withserver or client |
---|---|---|---|
- | .set, .update, .with | .with | .opt_with |
Clone | .cloned | .cloned | .opt_cloned |
Copy | .get | .get | .opt_get |
§Example
use reactive_signals::{runtimes::ClientRuntime, signal};
// signals are created in scopes
let sx = ClientRuntime::new_root_scope();
// a simple data value
let count = signal!(sx, 5);
// a simple string value
let name = signal!(sx, "kiwi");
// is_plural will update when count changes
let is_plural = signal!(sx, move || count.get() != 1);
// we'll keep a history of all changes
let history = signal!(sx, Vec::<String>::new());
let text = signal!(sx, move || {
let ending = if is_plural.get() { "s" } else { "" };
let txt = format!("{} {}{ending}", count.get(), name.get());
// using .update we can add the text to the vec without cloning the vec
history.update(|hist| hist.push(txt.clone()));
txt
});
assert_eq!(text.cloned(), "5 kiwis");
// when setting to same value the subscribers are not notified.
name.set("kiwi");
assert_eq!(history.with(|h| h.join(", ")), "5 kiwis");
// when changing the count the name and is_plural are updated automatically.
count.set(1);
assert_eq!(text.cloned(), "1 kiwi");
// you can update the name
name.update(|t| *t = "fig");
assert_eq!(text.cloned(), "1 fig");
// 1 kiwi is repated because when changing count, is_plural changes as well
// triggering a second update of the text. This will be detected in
// future versions and only notified once.
assert_eq!(
history.with(|h| h.join(", ")),
"5 kiwis, 1 kiwi, 1 kiwi, 1 fig"
);
with_signal_arg(count);
// when declaring functions some additional imports are necessary
use reactive_signals::{runtimes::Runtime, Signal, types::*};
fn with_signal_arg<RT: Runtime>(count: Signal<EqData<i32>, RT>) {
}
Implementations§
Source§impl<T, RT> Signal<T, RT>where
T: SignalType + Modifiable,
RT: Runtime,
impl<T, RT> Signal<T, RT>where
T: SignalType + Modifiable,
RT: Runtime,
Sourcepub fn set(&self, val: T::Inner)
pub fn set(&self, val: T::Inner)
Set the signal’s value and notifies subscribers
if the value changed when it implements PartialEq
otherwise it always notifies.
Sourcepub fn update<R: 'static>(&self, f: impl Fn(&mut T::Inner) -> R) -> R
pub fn update<R: 'static>(&self, f: impl Fn(&mut T::Inner) -> R) -> R
Applies a function to the current value to mutate it in place and returns whatever that function returns.
Subscribers are notified if the value changed when it implements PartialEq otherwise it always notifies.
Example of using the return value
let count = signal!(sc, 2);
let is_even = count.update(|val| {
*val += 1;
*val % 2 == 0
});
Source§impl<T, RT> Signal<T, RT>where
T: SignalType + Readable,
RT: Runtime,
impl<T, RT> Signal<T, RT>where
T: SignalType + Readable,
RT: Runtime,
Sourcepub fn with<R: 'static>(&self, f: impl Fn(&T::Inner) -> R) -> R
pub fn with<R: 'static>(&self, f: impl Fn(&T::Inner) -> R) -> R
Applies a function to the current value to mutate it in place and returns whatever that function returns.
Subscribers are notified if the value changed when it implements PartialEq
otherwise it always notifies.
Example of using the return value
let count = signal!(sc, 2);
let is_even = count.with(|val| *val % 2 == 0);
Source§impl<T, RT> Signal<T, RT>where
T: SignalType + OptReadable,
T::Inner: Clone,
RT: Runtime,
impl<T, RT> Signal<T, RT>where
T: SignalType + OptReadable,
T::Inner: Clone,
RT: Runtime,
Sourcepub fn opt_cloned(&self) -> Option<T::Inner>
pub fn opt_cloned(&self) -> Option<T::Inner>
Get a clone of the signal value (if the value implements Clone)
Use the .with()
function if you can in order to avoid the clone.
Source§impl<T, RT> Signal<T, RT>where
T: SignalType + OptReadable,
RT: Runtime,
impl<T, RT> Signal<T, RT>where
T: SignalType + OptReadable,
RT: Runtime,
Sourcepub fn opt_with<R: 'static>(&self, f: impl Fn(&T::Inner) -> R) -> Option<R>
pub fn opt_with<R: 'static>(&self, f: impl Fn(&T::Inner) -> R) -> Option<R>
Applies a function to the current value to mutate it in place and returns whatever that function returns.
Subscribers are notified if the value changed when it implements PartialEq
otherwise it always notifies.
Example of using the return value
let count = signal!(sc, 2);
let is_even = count.with(|val| *val % 2 == 0);