Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

sync_signal

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

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_sync_signal::sync_signal;

#[component]
fn Demo() -> impl IntoView {
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

view! { }
}

RwSignal

You can mix and match RwSignals and Signal-WriteSignal pairs.

use leptos::prelude::*;
use leptos_use_sync_signal::sync_signal;

#[component]
fn Demo() -> impl IntoView {
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);


view! { }
}

One directional

You can synchronize a signal only from left to right or right to left.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions, SyncDirection};

#[component]
fn Demo() -> impl IntoView {
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

view! { }
}

Custom Transform

You can optionally provide custom transforms between the two signals.

use leptos::prelude::*;
use leptos::logging::log;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions};

#[component]
fn Demo() -> impl IntoView {
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

view! { }
}

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.

use leptos::prelude::*;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions};
use std::str::FromStr;

#[component]
fn Demo() -> impl IntoView {
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(),
    ),
);

view! { }
}
use leptos::prelude::*;
use leptos_use_sync_signal::{sync_signal_with_options, SyncSignalOptions};
use std::str::FromStr;

#[derive(Clone)]
pub struct Foo {
    bar: i32,
}

#[component]
fn Demo() -> impl IntoView {
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,
    ),
);

view! { }
}

Server-Side Rendering

Make sure you follow the instructions in 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.

Installation

cargo add leptos-use-sync-signal

Options

SyncSignalOptions

Options for sync_signal_with_options.

Every option is set with a builder method of the same name, e.g. SyncSignalOptions::default().immediate(...). See also the API docs.

immediate

Type: bool

If true, the signals will be immediately synced when this function is called. If false, a signal is only updated when the other signal’s value changes. Defaults to true.

direction

Type: SyncDirection

Direction of syncing. Defaults to SyncDirection::Both.

Source

Source • Demo • Docs