adding `set_fn` and `set_fn_silent` (#529)

* adding change and change_silent

* using name set_fn to more clearly align with set

* Use `f` for function name

Co-authored-by: Luke <37006668+lukechu10@users.noreply.github.com>

* Use `f` for function name

Co-authored-by: Luke <37006668+lukechu10@users.noreply.github.com>

Co-authored-by: Luke <37006668+lukechu10@users.noreply.github.com>
This commit is contained in:
Blaine Hansen 2022-11-14 06:38:53 -07:00 committed by GitHub
parent 5d49777b4a
commit 568b5b13c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 32 additions and 0 deletions

View File

@ -228,6 +228,25 @@ impl<T> Signal<T> {
self.trigger_subscribers();
}
/// Set the value of the state using a function that receives the current value.
///
/// This will notify and update any effects and memos that depend on this value.
///
/// # Example
/// ```
/// # use sycamore_reactive::*;
/// # create_scope_immediate(|cx| {
/// let state = create_signal(cx, 0);
/// assert_eq!(*state.get(), 0);
///
/// state.set_fn(|n| n + 1);
/// assert_eq!(*state.get(), 1);
/// # });
/// ```
pub fn set_fn<F: Fn(&T) -> T>(&self, f: F) {
self.set(f(&self.get_untracked()));
}
/// Set the current value of the state wrapped in a [`Rc`]. Unlike [`Signal::set()`], this
/// method accepts the value wrapped in a [`Rc`] because the underlying storage is already using
/// [`Rc`], thus preventing an unnecessary clone.
@ -258,6 +277,13 @@ impl<T> Signal<T> {
self.set_rc_silent(Rc::new(value));
}
/// Set the value of the state using a function that receives the current value _without_ triggering subscribers.
///
/// Make sure you know what you are doing because this can make state inconsistent.
pub fn set_fn_silent<F: Fn(&T) -> T>(&self, f: F) {
self.set_silent(f(&self.get_untracked()));
}
/// Set the current value of the state wrapped in a [`Rc`] _without_ triggering subscribers.
///
/// See the documentation for [`Signal::set_rc()`] for more information.
@ -636,6 +662,9 @@ mod tests {
state.set(1);
assert_eq!(*state.get(), 1);
state.set_fn(|n| n + 1);
assert_eq!(*state.get(), 2);
});
}
@ -660,6 +689,9 @@ mod tests {
assert_eq!(*double.get(), 0);
state.set_silent(1);
assert_eq!(*double.get(), 0); // double value is unchanged.
state.set_fn_silent(|n| n + 1);
assert_eq!(*double.get(), 0); // double value is unchanged.
});
}