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

Hydration errors style attribute since vue 3.4 #10336

Closed
nestle49 opened this issue Feb 13, 2024 · 5 comments
Closed

Hydration errors style attribute since vue 3.4 #10336

nestle49 opened this issue Feb 13, 2024 · 5 comments

Comments

@nestle49
Copy link

Vue version

3.4.19

Link to minimal reproduction

#10335

Steps to reproduce

  1. Create 2 DOM elements any ssr
  2. Create dependence style first element from style another, for example
<div :style="{ paddingRight: `${width + 10}px` }">
 Content
</div>

<button ref="cartButton">
Cart button
</button>
const cartButton = ref<HTMLElement>()
    const { width } = useElementSize(cartButton, undefined, {
        box: 'border-box'
    })

I tried using the onMounted hook but it doesn't seem to guarantee that the hydration process is complete, it seems like a bug. Is this really something that deserves warning?

this is more of a theoretical question, so I don't think reproduction is necessary, you can reproduce it in any minimal SSR

It seems that any style dependency on another style that changes on the client will give an error. We don't understand the concept?

What is expected?

No hydration errors

What is actually happening?

Hydration errors

Снимок экрана 2024-02-13 в 15 00 46

System Info

System:
    OS: macOS 14.3
    CPU: (8) arm64 Apple M1
    Memory: 69.20 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.5.1 - ~/.nvm/versions/node/v20.5.1/bin/node
    npm: 9.8.0 - ~/.nvm/versions/node/v20.5.1/bin/npm
  Browsers:
    Chrome: 121.0.6167.160
    Safari: 17.3
  npmPackages:
    vue: ^3.4.19 => 3.4.19

Any additional comments?

No response

@nestle49
Copy link
Author

nestle49 commented Feb 13, 2024

upd. isMounted inside a component solves the problem, but should we add a check everywhere? It's almost as if :style itself is defective

:style="{ paddingRight: isMounted ? ${widthCartButton + 10}px : 0 }"

upd2. Is there some kind of lifecycle hook that would indicate the end of hydration of the entire application?

@yyx990803
Copy link
Member

We don't know what useElementSize is doing underneath, please provide a runnable reproduction instead of code snippets.

@DaniilIsupov
Copy link

DaniilIsupov commented Feb 16, 2024

We don't know what useElementSize is doing underneath, please provide a runnable reproduction instead of code snippets.

I made minimal reproduction: https://github.com/DaniilIsupov/reproduction-hydration
In my example at App.vue I can't wait when all child components are mounted
Because of this prop.count value is being updated until hydration is complete

image

@nestle49
Copy link
Author

We don't know what useElementSize is doing underneath, please provide a runnable reproduction instead of code snippets.

I made minimal reproduction: https://github.com/DaniilIsupov/reproduction-hydration In my example at App.vue I can't wait when all child components are mounted Because of this prop.count value is being updated until hydration is complete

image

Yes, this is the crux of the problem

useElementSize is a VueUse helper, but that's not important

The fact is that in large difficulty applications, some components are mounted before others, which leads to hydration errors when changing some parameters depending on the client side. In my case, VueUse useElementSize passes the width from the client and causes the style attribute of the not yet mounted component to change and throws an error

However, this is very difficult to reproduce in a minimal example, since the components are mounted almost simultaneously

Therefore, when accessing a client entity in one place, we cannot be sure that all components in which changes will occur have already been mounted and hydration has been completed

@edison1105
Copy link
Member

edison1105 commented Nov 4, 2024

@nestle49
useElementSize().width should return 0 on the server side, and the correct element size on the client side.

@DaniilIsupov
The following code will only execute on the client, not the server. Therefore, the count will differ.

onMounted(() => {
    console.log('App.vue')

    count.value += 1
})

use data-allow-mismatch to suppress hydration mismatch warnings.
https://vuejs.org/api/ssr.html#data-allow-mismatch

@edison1105 edison1105 closed this as not planned Won't fix, can't repro, duplicate, stale Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants