DioxusLabs / DioxusLabs/dioxus

When `onmounted` is called, element dimensions are incorrect

Open
#1,093 0 comments 0 reactions 0 assignees View on GitHub
bug consistency desktop
Dominant language
Rust
Stars
39.1k
Forks
1.9k
Avg merge
4d 10h
Merged PRs (30d)
4

Description

**Problem**

Via both the `onmounted` event data and via javascript, I have seen that when an async function is called inside an `onmounted` event, the reported width and height of an element is incorrect. The fact that this is seen in two ways is suggestive that when the user makes use of `onmounted` the DOM elements are not laid out as they will be when rendering is complete.

When I say that the dimensions are correct, what I have typically seen is that for say 10 elements being laid out, the first two should have height of 250px each, but reported numbers are 900px and 1200px, then the remaining 8 are reported correctly.

**Steps To Reproduce**

I couldn't reproduce this behaviour. I see it in a larger app I'm building. The gist of the code is:

```
# this all takes place inside the component
let eval = dioxus_desktop::use_eval(cx);
let tree_data: &UseRef> = use_ref(cx, || DependencyTree::new(&cx.props.p));
cx.render(rsx!(
div {
position: "relative",
tree_data.read().children.iter().map(|(id, node)| {
let id = id.clone();
rsx!(
div {
key: "{id}",
position: "absolute",
top: "{node.position.y}px",
left: "{node.position.x}px",
onmounted: move |_| {
let tree_data = tree_data.clone();
let t = cx.props.p.clone();
to_owned![eval];
cx.spawn(async move {
// sleep(Duration::from_millis(100)).await; // Adding this line solves the issue.
if let Ok(res) = eval(js_get_element_dimensions(id)).await {
let width = res.as_array().unwrap().get(0).unwrap().as_f64().unwrap();
let height = res.as_array().unwrap().get(1).unwrap().as_f64().unwrap();
# This is where we actually make use of the width and height we've obtained
tree_data.write_silent().children.get_mut(&id).unwrap().size = Some(Size2D::new(width, height));
}
});

},
}
)
})
}))
```
Outside the component define the JavaScript function that will fetch the element dimensions:
```
fn js_get_element_dimensions(id: u64) -> String {
format!(r#"
const el = document.getElementById("{id}");
let width = el.offsetWidth;
let height = el.offsetHeight;
return [width, height];
"#).to_string()
}
```

You can also see the runnable example given in [this issue](https://github.com/DioxusLabs/dioxus/issues/1092), which doesn't reproduce the issue, but perhaps could quite quickly if we knew what we were looking for.

**Expected behavior**

Since I do not adjust the size of any element dynamically (I adjust their absolute position) I expect all elements to have the same size reported as is shown if I _inspect element_ on them.

**Environment:**
- Dioxus version: `b476c6e8a73bd6591ec4827c6f9b196d7c270c3d` (from master)
- Rust version: 1.69.0
- OS info: MacOS
- App platform: `desktop`

**Questionnaire**

- [ ] I'm interested in fixing this myself but don't know where to start
- [ ] I would like to fix and I have a solution
- [ ] I don't have time to fix this right now, but maybe later

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.