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

bug: using useAccount address causes hydration error #453

Closed
1 task done
technophile-04 opened this issue Jul 26, 2023 · 6 comments · Fixed by #458
Closed
1 task done

bug: using useAccount address causes hydration error #453

technophile-04 opened this issue Jul 26, 2023 · 6 comments · Fixed by #458

Comments

@technophile-04
Copy link
Collaborator

technophile-04 commented Jul 26, 2023

Is there an existing issue for this?

Current Behavior

It seems that displaying simple address from useAccount give "Hydration Error" :

Screenshot 2023-07-26 at 8 52 18 PM

Steps To Reproduce

Screenshot 2023-07-26 at 8 55 29 PM

Anything else?

I was just trying to reproduce this normal wagmi-rainbowkit starter kit using create-wagmi

But it seems that they are using very latest version of next and they have wrapped whole logic in the component which is marked as "use client" checkout -> https://github.com/technophile-04/wagmi-debug/blob/750944c40657d94bf503878108b660d87a7e32d7/src/components/Connected.tsx#L1

I will try to debug it more in SE-2 itself but CCing @carletex @rin-st @sverps if something clicks up

@rin-st
Copy link
Member

rin-st commented Jul 27, 2023

It works as it should - there is no account on the server, so there is a mismatch.

Why it works on their side? Well, it took some time to find. Look what those cheaters do in src/app/layout (it's a layout for the whole app) and especially src/app/providers. Basically, they don't use ssr inside providers, only client rendering

@technophile-04
Copy link
Collaborator Author

Actually, this worked before like it used not to give a Hydration error : (

I tried traveling through commits and it seems something broke at -> fb3fcd6 Fix auto connect (#412)

If you checkout to its parent commit -> cc1af9f fix: type issues when multiple contracts deployed (#410) there it seems to work without any hydration issues

@rin-st
Copy link
Member

rin-st commented Jul 28, 2023

cc1af9f - wagmi config autoConnect was false. We used custom useAutoConnect and it connected after the first renders. Log address - it's undefined on the first renders, so there is no hydration error.

After #412 it changed, wagmi config autoConnect is true, so useAccount has data on the first render. It's good for react apps but not so good for next because that hydration error appears.

To fix it we can write a simple wrapper using useMounted, so there will be no error.

@technophile-04
Copy link
Collaborator Author

technophile-04 commented Jul 28, 2023

Description :

So I have been tinkering in the branch play/useAutoConnect-useAccount and setup few things there to test :

  1. Put useAutoConnect back from Fix/auto connect #412
  2. Setup our own useLocalStorage which is just copy-past from useHooks-ts (without patch i.e bug: hydration fails due to mismatch caused by usehooks-ts bug #340) to tinker around
  3. Have 2 contracts for deployment to test Save selected contract to local storage #326 (comment)

Now if you try auto connect functionality it works since we do not have patch in place i.e we are using readValue in useState of useLocalStorage instead of patch i.e -> https://github.com/juliencrn/usehooks-ts/pull/251/files

When using useLocalStorage with readValue the auto connect functionality works nicely but this problem arises -> #326 (comment) :

YourContarct is selected but not highlight hydration warning in console
Screenshot 2023-07-28 at 6 58 53 PM Screenshot 2023-07-28 at 6 58 31 PM

Now once you change the value into initialValue in useState of useLocalStrage(using patch proposed in #340 ) here ->

const [storedValue, setStoredValue] = useState<T>(readValue);

We have auto connect broken but now the debug contracts page works nicely


Some Solutions :

  1. Patch useLocalStorage in such way that it handle's both cases nicely (I tried doing but it was kindof out my mind to think and handle cases but need to spend more time figuring out )
  2. Keep everything as it is and create wrapper's around hooks as suggested by Rinnat in (bug: using useAccount address causes hydration error #453 (comment)) ( If it was only hook useAccount then this solution seem feasible but I see others breaks too like useNetwork )
  3. Use hacky solution propose in Fix/useAccount & some other hooks hydration issue  #458
  4. Please feel free to suggest any other better solution if they come to your mind 🙌

@rin-st
Copy link
Member

rin-st commented Jul 29, 2023

Gj Shiv!

I think custom solutions like useAutoConnect can work differently than wagmis autoConnect option, because we don't know if there are edge cases or something we don't count. Additionally it adds some complexity. Also, we should avoid hacky solutions because again it becomes difficult to debug.

I think you have already seen this wevm/wagmi#542 . There is no official solution, they propose to use useMounted for the full app or everywhere where hooks are used, and some people propose something like custom useAutoConnect. Or to use persister: false but I think it's not good

I think the easiest way is to use a wrapper for every broken hook because it's easy to understand and maintain, it doesn't break wagmis autoconnect. Don't know why no one proposed it :)

Something like this

import { useEffect, useState } from "react";
import { useAccount } from "wagmi";

export function useMountedAccount(...args: Parameters<typeof useAccount>) {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);
  }, []);

  const useAccountRes = useAccount(...args);

  return mounted ? useAccountRes : ({} as ReturnType<typeof useAccount>);
}

please lmk if I don't consider something and let's see what others think


upd. I understood what's wrong with my solution, there are values in useAccount() that shouldn't be falsy on the first render, but in my hook everything is undefined, so it can cause bugs. I can write default values but again it's very difficult to maintain. So probably your solution is better

@technophile-04
Copy link
Collaborator Author

values in useAccount() that shouldn't be falsy on the first render, but in my hook everything is undefined, so it can cause bugs. I can write default values but again it's very difficult to maintain.

Ohh yeah this makes sense and yup it will be hard to maintain also we will be needing to do same for other breaking hooks too, lol It didn't come to my mind until you mentioned 🙌

I think custom solutions like useAutoConnect can work differently than wagmis autoConnect option, because we don't know if there are edge cases or something we don't count. Additionally, it adds some complexity. Also, we should avoid hacky solutions because again it becomes difficult to debug.

Yup, I completely get this feeling!! and I agree it's not the best solution but since we have been using custom useAutoConect from the beginning of SE-2 and it was working fine there, I have just copy pasted it and added a few lines in #458, yup and it was also suggested by Tmm here wevm/wagmi#542 (comment)

Also, I have been taking a look at other protocols / SDK's docs and they suggest adding custom useAutoConnect for working nicely with them example checkout Safe apps sdk wagmi integration, I also remember one AA SDK doing similar

We can also mention about this in our SE-2 docs, saying we are using custom "useAutoConnect" to handle auto-connect and if you need any third-party integration which requires useAutoConnect you can add logic there


Saying that it's great to keep an eye on wevm/wagmi#542 because they said that they will internally handle this once NEXT.js 13 is stable enough 🙌 and also let's see what others have to tell

But Thanks for the input and digging as always 🙌

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

Successfully merging a pull request may close this issue.

2 participants