#storing component in context causes the component internal state updates to not happen.

1 messages · Page 1 of 1 (latest)

hexed crater
#
impl ModalState {
    pub fn close(&mut self) {
        println!("Close modal");
        self.open = false;
        self.heading.clear();
        self.child = None;
    }

    pub fn open(&mut self, heading: String, element: Element) {
        println!("Open modal");
        self.open = true;
        self.heading = heading;
        self.child = Some(element);
    }
}

pub fn Modal() -> Element {
    let mut modal_state = consume_context::<Signal<ModalState>>();

    rsx!(
        div { {modal_state().child.unwrap_or(rsx!()) } }
    )
}


// calling code.
            button {
               
                onclick: move |_| {
                    modal_state.write().open("Create new project".to_string(), NewProject())
                },
                "Create a new project"
            }



I am having all event listeners work but state updates on child components don't work mounting the component directly somewhere else.

What I am trying to do is render a component in modal (shared state through context) only when a component needs t be opened in modal.

#

storing component in context causes the component internal state updates to not happen.

loud stirrup
#

If NewProject is a component that uses hooks, you shouldn't call it like a normal function because it breaks the rules of hooks

#

You could change the modal class to accept a component (fn() -> Element) and render that component inside of rsx instead of an element

#
pub fn Modal() -> Element {
    let mut modal_state = consume_context::<Signal<ModalState>>();
    let Comp = modal_state().child;

    rsx!(
        div { Comp {} }
    )
}
hexed crater
#

setting child to NewProject in both open and close muations doesn't help either.

#

@loud stirrup Thanks for the help!! that was enough to get it working!! There was some runtime issue regarding navigator can only be route artifact of some old approach.

hexed crater
#

I encountered a really weird issue it only shows up when I use Comp {} twice, or else

div { class: "p-4 pb-0 min-w-screen-md", Comp {} }
// Double Comp {} required I don't know why
div { class: "hidden", Comp {} }

loud stirrup
#

Are you diffing comp?

hexed crater
#

Sorry, what does that mean?

loud stirrup
#

Do you change the modal_state signal?

#

That would cause Comp {} to be diffed

hexed crater
#

I use the mut self method on ModalState when open is called

#

That is how I open a modal in sidebar: modal_state.open("<heading>", ComponentToRender);

#
impl ModalState {
    pub fn close(&mut self) {
        self.open = false;
        self.heading.clear();
        self.child = || rsx!(  );
    }

    pub fn open(&mut self, heading: String, element: fn()->Element) {
        self.open = true;
        self.heading = heading;
        self.child = element;
    }
}
loud stirrup
#

Diffing component pointers doesn't seem to be working. This never renders comp2:

use dioxus::prelude::*;

fn main() {
    launch(app);
}

fn app() -> Element {
    let Comp1 = || {
        let mut signal = use_signal(|| 0);
        rsx! {button {
            onclick: move |_| signal += 1,
            "Click me: {signal}"
        }}
    };

    let Comp2 = || {
        let mut signal = use_signal(|| 0);
        rsx! {button {
            onclick: move |_| signal -= 1,
            "Click me #2: {signal}"
        }}
    };

    let mut count = use_signal(|| 0);
    let Comp = match count() % 2 {
        0 => Comp1,
        _ => Comp2,
    };

    rsx! {
        h1 { "High-Five counter: {count}" }
        button { onclick: move |_| count += 1, "Up high!" }
        button { onclick: move |_| count -= 1, "Down low!" }
        Comp {}
    }
}
#

You could try to make something like Box<dyn ComponentFunction<()>> work instead