-
Notifications
You must be signed in to change notification settings - Fork 13
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
Add use_window_resize_status hook #47
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From how I see it, a new hook is unnecessary. Instead, I would modify the existing use_window_size
hook so it checks whether the size is really different or not:
pub fn use_window_size() -> ReadOnlySignal<WindowSize> {
let mut window_size = use_signal(get_window_size);
// Initialize the handler
let tx = use_coroutine(|mut rx: UnboundedReceiver<WindowSize>| async move {
while let Some(data) = rx.next().await {
if *window_size.peek() != data {
window_size.set(data);
}
}
});
listen(tx);
use_hook(|| ReadOnlySignal::new(window_size))
}
But even after these changes I don't think it's going to make a different, if a resize event happened then it means the size really changed, there is not a single case where the signal is going to be updated with the exact same size
Can you maybe share a bit of context on how you are hitting this expensive computation? |
Hi Marc, thanks for taking a look so quickly. I think when it comes to simple cases where this hook is the only hook that will cause a component update you're right - there's no difference in the number of refreshes. but what if the content of a different hook in the component is changed? I'd like to choose what work to do based on which hook caused the refresh. Let me know if there's a more idiomatic way of doing this, here is additional context: I am arranging a grid of draggable panels within a DragArea with the grid layout based on window size and I'd like to only run the sizing calculations when the window size changes instead of on every single component update of the parent DragArea. This component experiences many window-size-unrelated updates since itself and all of its direct child DragTargets and Draggables already have to rerender with every pointermove event while dragging. Here is a loose overview of the main logic:
here's what I am envisioning for the DragArea hooks:
|
I would suggest looking at #[component]
pub fn DragArea(children: Element) -> Element {
let global_drag_info = ...;
let drag_area_gird = ...;
let window_size = use_window_size();
use_effect(move || {
// This subscribes this effect to the signal returned by `use_window_size`
// and will only re-run when it's value changes.
let size = window_size();
// Do your computational code
drag_area_grid.write().set_new_size(size);
});
rsx!{...}
} See use_effect & use_memo |
Thanks for pointing out these two hooks - they look promising but I'm still encountering an issue this PR solves: signals written to from inside the
|
It is normal for signals themselves to be cloned but the value stored inside may or may not be depending on how it's used. In your case, the inner value shouldn't be cloned at all since |
I've investigated further and filed DioxusLabs/dioxus/#2565 to account for the issue I'm having with use_memo |
closing now that I have the |
Introduces a wrapper over the use_window_size hook that tells a component whether or not the window has been resized since the last update. This will help devs prevent expensive component size computations from running when not needed.