yew icon indicating copy to clipboard operation
yew copied to clipboard

callback not rendering when vector is passed as dep

Open t0mpl opened this issue 2 years ago • 2 comments

Hi, I'm trying to pass a state as dependency for a callback function, this state is a vector of struct, I get no compiler error, but the callback never update when the vector state is mutated.

Am I doing something wrong or is there a workaround to this problem?

thanks for your help.

let messages_handler: yew::UseStateHandle<Vec<Message>> = use_state(|| {
        vec![]
    });
    let messages_handler_value = (*messages_handler).clone();

    let on_new_message: Callback<Message, ()> = {
        let messages_handler = messages_handler.clone();
        let messages_handler_value = messages_handler_value.clone();

        use_callback(
            move |message: Message, messages_handler_value| {
                let mut messages_handler_value = messages_handler_value.clone();
                messages_handler_value.push(message);

                messages_handler.set(messages_handler_value);
            },
            messages_handler_value.clone(),
        )
    };

t0mpl avatar Jun 19 '23 12:06 t0mpl

I found a temporary solution by using a buffer

   let message_received_buffer_handle: UseStateHandle<Option<Message>> = use_state(|| None);
    let message_received_buffer_value = (*message_received_buffer_handle).clone();

    let messages_handler: yew::UseStateHandle<Vec<Message>> = use_state(|| vec![]);
    let messages_handler_value = (*messages_handler).clone();

    let on_new_message = {
        let message_received_buffer_handle = message_received_buffer_handle.clone();

        use_callback(
            move |message: Message, message_received_buffer_handle| {
                message_received_buffer_handle.set(Some(message));
            },
            message_received_buffer_handle,
        )
    };

    let connect = use_message_stream(UseMessageStreamProps {
        on_new_message: on_new_message,
    });

    {
        let  mut messages_handler_value = messages_handler_value.clone();
        let messages_handler = messages_handler.clone();

        use_effect_with_deps(
            move |message_buffered| {
                let message = match message_buffered {
                    Some(message) => message,
                    None => return,
                };
                
                match messages_handler_value.last() {
                    Some(last_message) => {
                        if last_message == message {
                            return;
                        }
                    }
                    None => (),
                };

                messages_handler_value.push(message.to_owned());
                messages_handler.set(messages_handler_value)
            },
            message_received_buffer_value,
        );
    }

t0mpl avatar Jun 20 '23 16:06 t0mpl

Is this actually a bug? I think what happened here is that the line

let messages_handler_value = (*messages_handle).clone();

defines not a state handle, but a Vec, you've simply cloned the inner vector so there's no longer any association of it with the handle. I'd consider closing this issue.

its-the-shrimp avatar Oct 19 '23 12:10 its-the-shrimp