pub fn sync_signal<T>(
left: impl Into<UseRwSignal<T>>,
right: impl Into<UseRwSignal<T>>,
) -> impl Fn() + Clone
Expand description
Two-way Signals synchronization.
Note: Please consider first if you can achieve your goals with the “Good Options” described in the Leptos book Only if you really have to, use this function. This is, in effect, the “If you really must…” option.
§Demo
§Usage
let (a, set_a) = signal(1);
let (b, set_b) = signal(2);
let stop = sync_signal((a, set_a), (b, set_b));
log!("a: {}, b: {}", a.get(), b.get()); // a: 1, b: 1
set_b.set(3);
log!("a: {}, b: {}", a.get(), b.get()); // a: 3, b: 3
set_a.set(4);
log!("a: {}, b: {}", a.get(), b.get()); // a: 4, b: 4
§RwSignal
You can mix and match RwSignal
s and Signal
-WriteSignal
pairs.
let (a, set_a) = signal(1);
let (b, set_b) = signal(2);
let c_rw = RwSignal::new(3);
let d_rw = RwSignal::new(4);
sync_signal((a, set_a), c_rw);
sync_signal(d_rw, (b, set_b));
sync_signal(c_rw, d_rw);
§One directional
You can synchronize a signal only from left to right or right to left.
let (a, set_a) = signal(1);
let (b, set_b) = signal(2);
let stop = sync_signal_with_options(
(a, set_a),
(b, set_b),
SyncSignalOptions::default().direction(SyncDirection::LeftToRight)
);
set_b.set(3); // doesn't sync
log!("a: {}, b: {}", a.get(), b.get()); // a: 1, b: 3
set_a.set(4);
log!("a: {}, b: {}", a.get(), b.get()); // a: 4, b: 4
§Custom Transform
You can optionally provide custom transforms between the two signals.
let (a, set_a) = signal(10);
let (b, set_b) = signal(2);
let stop = sync_signal_with_options(
(a, set_a),
(b, set_b),
SyncSignalOptions::with_transforms(
|left| *left * 2,
|right| *right / 2,
),
);
log!("a: {}, b: {}", a.get(), b.get()); // a: 10, b: 20
set_b.set(30);
log!("a: {}, b: {}", a.get(), b.get()); // a: 15, b: 30
§Different Types
SyncSignalOptions::default()
is only defined if the two signal types are identical.
Otherwise, you have to initialize the options with with_transforms
or with_assigns
instead
of default
.
let (a, set_a) = signal("10".to_string());
let (b, set_b) = signal(2);
let stop = sync_signal_with_options(
(a, set_a),
(b, set_b),
SyncSignalOptions::with_transforms(
|left: &String| i32::from_str(left).unwrap_or_default(),
|right: &i32| right.to_string(),
),
);
#[derive(Clone)]
pub struct Foo {
bar: i32,
}
let (a, set_a) = signal(Foo { bar: 10 });
let (b, set_b) = signal(2);
let stop = sync_signal_with_options(
(a, set_a),
(b, set_b),
SyncSignalOptions::with_assigns(
|b: &mut i32, a: &Foo| *b = a.bar,
|a: &mut Foo, b: &i32| a.bar = *b,
),
);
§Server-Side Rendering
On the server the signals are not continuously synced. If the option immediate
is true
, the
signals are synced once initially. If the option immediate
is false
, then this function
does nothing.