Passing global state (e.g. app preferences) to components #552
chriskilding
started this conversation in
Ideas
Replies: 1 comment 3 replies
-
Thinking about this some more, we probably don't want to share the common variables directly, because this goes against the grain of the CSP-style communication between components that normally happens. Instead, we want the ability to send events about the common variables to all components. Something like this... enum MyEnvironmentInput {
Sensitive,
NotSensitive,
}
struct App {
// any view-local state, as normal
}
enum AppInput {
// events specific to App
}
#[relm4::component(pub)]
impl SimpleComponent for App {
type Input = AppInput;
type EnvironmentInput = MyEnvironmentInput;
view! {
#[root]
gtk::Box {
// embeds Foo (and many other components)
}
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
// process AppInput messages as usual
}
fn update_environment(&mut self, message: Self::EnvironmentInput, sender: ComponentSender<Self>) {
// process EnvironmentInput messages
}
}
struct Foo {
sensitive: bool,
// plus any view-local state
}
enum FooInput {
DoSomething,
}
#[relm4::component(pub)]
impl SimpleComponent for Foo {
type Input = FooInput;
type EnvironmentInput = MyEnvironmentInput;
view! {
#[root]
gtk::Button {
set_label: "Do something",
#[watch]
set_sensitive: model.sensitive,
connect_clicked => FooInput::DoSomething,
}
}
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
// process FooInput messages as usual
match message {
FooInput::DoSomething => {}
}
}
fn update_environment(&mut self, message: Self::EnvironmentInput, sender: ComponentSender<Self>) {
// process EnvironmentInput messages
match message {
MyEnvironmentInput::Sensitive => {},
MyEnvironmentInput::NotSensitive => {},
}
}
} |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Occasionally I have a need to share a variable with a lot of components within the app. (Not document state which I've mentioned before; I mean more like app preferences variables.)
I'm aware of the example which uses a static global
SharedState
instance to share this kind of information. However a static global variable impacts the testability of components, so I'm wondering whether there is a better way.In SwiftUI there is a concept of an
@EnvironmentObject
- an object that's placed into the app's global environment. (Tutorial available at https://www.avanderlee.com/swiftui/environmentobject/). This design is neat in that it lets you achieve the deduplication of code, while retaining testability (just insert a mock of the environment object when you instantiate the SwiftUI view in tests, i.e.MyView().environmentObject(mock))
.Could we somehow translate this into Relm4? Perhaps something like this...
Beta Was this translation helpful? Give feedback.
All reactions