'My dapp doesn't detect when an user change their Metamask Account

I am in the process of building a dapp for a project. I have one last thing to adjust: detect when a user changes metamask account to reset the state but it doesn't work.

//Doesn't work
window.ethereum.on('accountsChanged', function (accounts) {
        console.log('accountsChanges',accounts);
        setDefaultAccount(null)
});

// This works perfectly
window.ethereum.on('chainChanged', (chainId) => {
            if(chainId !== "0x13881") {
                setErrorMessage("Please connect on testnet Polygon Mumbai")
            } else {
                setErrorMessage(null)
                window.location.reload();
   }

Thank for your help !



Solution 1:[1]

I was also struggling with the same issue. Being unable to find the answer in the docs anywhere. Until I'd realized that it's not meant to detect you switching from a connected account to a disconnected one.

In other words: it only detects it when you switch between accounts that are already connected to your Dapp. In that case - it functions perfectly. And detects an account change.

Go on ahead an test it on some popular Dapp out there. Connect just one of your accounts to it - then change it to another account on the same wallet, that is not yet connected - and it will also not be able to detect you changing it. But if you connect two accounts right away - it will detect you switching between them and reflect your changes on its interface.

I tested this with PCS.

Solution 2:[2]

this is the correct way of implementation:

useEffect(() => {
      ethereum?.on("accountsChanged", handleAccountChange);
      return () => {
        ethereum?.removeListener("accountsChanged", handleAccountChange);
      };
    });

Now write a listener for account change

const handleAccountChange = (...args) => {
      // you can console to see the args
      const accounts = args[0] ;
      // if no accounts that means we are not connected
      if (accounts.length === 0) {
        console.log("Please connect to metamask");
        // our old data is not current connected account
        // currentAccount account that you already fetched and assume you stored it in useState
      } else if (accounts[0] !== currentAccount) {
        // if account changed you should update the currentAccount so you return the updated the data
        // assuming you have [currentAccount,setCurrentAccount]=useState
        // however you are tracking the state currentAccount, you have to update it. in case of redux you have to dispatch update action etc
        setCurrentAccount(accounts[0)
      }
    };

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Yilmaz