Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Example] Shared state between different component events #31

Open
matthewharwood opened this issue Jun 27, 2020 · 2 comments
Open

[Example] Shared state between different component events #31

matthewharwood opened this issue Jun 27, 2020 · 2 comments
Labels
cookbook Things to put in the cookbook

Comments

@matthewharwood
Copy link

matthewharwood commented Jun 27, 2020

Looking for examples on how we would share state between different events:

Borrowing from your README.md Example.

I'd like to see an example where we render 2 buttons and they share the clicks state.

Heres a React Example: of what I mean
https://codesandbox.io/s/isolated-vs-shared-q2ii5?file=/src/App.tsx

Mogwai code:

extern crate log;
extern crate console_log;
extern crate console_error_panic_hook;
extern crate mogwai;
extern crate serde;
extern crate serde_json;

use log::Level;
use mogwai::prelude::*;
use std::panic;
use wasm_bindgen::prelude::*;


// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;



pub struct Button {
  pub clicks: i32
}

#[derive(Clone)]
pub enum ButtonIn {
  Click
}

#[derive(Clone)]
pub enum ButtonOut {
  Clicks(i32)
}

impl Component for Button {
  type ModelMsg = ButtonIn;
  type ViewMsg = ButtonOut;
  type DomNode = HtmlElement;

  fn update(
    &mut self,
    msg: &ButtonIn,
    tx_view: &Transmitter<ButtonOut>,
    _subscriber: &Subscriber<ButtonIn>
  ) {
    match msg {
      ButtonIn::Click => {
        self.clicks += 1;
        tx_view.send(&ButtonOut::Clicks(self.clicks))
      }
    }
  }

  fn view(
    &self,
    tx: Transmitter<ButtonIn>,
    rx: Receiver<ButtonOut>
  ) -> Gizmo<HtmlElement> {
    button()
      .rx_text("Clicked 0 times", rx.branch_map(|msg| {
        match msg {
          ButtonOut::Clicks(n) => format!("Clicked {} times", n)
        }
      }))
      .tx_on("click", tx.contra_map(|_| ButtonIn::Click))
  }
}

#[wasm_bindgen]
pub fn main() -> Result<(), JsValue> {
  panic::set_hook(Box::new(console_error_panic_hook::hook));
  console_log::init_with_level(Level::Trace)
    .unwrap();
    div().with(
      Button{ clicks: 0 }.into_component()
    ).with(
      Button{ clicks: 0 }.into_component()
    )
    .run()
}
@schell schell added the cookbook Things to put in the cookbook label Jun 30, 2020
@schell
Copy link
Owner

schell commented Jun 30, 2020

Typically the state would only be shared between buttons within the same component - components are meant to talk to each other using messages. Though you could accomplish this by using a shared variable between them (Arc<Mutex<u32>> or Rc<Cell<u32>>). I'll add this to the cookbook.

@matthewharwood
Copy link
Author

components are meant to talk to each other using messages

Maybe this is what I'm missing then. Maybe we show it using Arc<Mutex<u32>> and then show the more idiomatic "message" passing example

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cookbook Things to put in the cookbook
Projects
None yet
Development

No branches or pull requests

2 participants