[SOLVED] Moralis onAccountChanged() causing memory leak

Was recently making a project using Moralis where I used it for user Auth.
When implemented I want when a user is inside app, and if user switches his account the address should update on app as well. So on going through docs I found onAccountChanged() for that. It works fine but causing Memory leak warning.

const Dashboard = () => {
  const { Moralis, isAuthenticated, user, logout } = useMoralis();
  const [userAddress, setUserAddress] = useState();
  const router = useRouter();

  const handleLogout = async () => {
    await logout();
    console.log("logged out");
  };

  // UseEffect with onAccountChanged() causing Memory Leak -------------
  useEffect(() => {
  // Account switching
  Moralis.onAccountChanged(async (chain) => {
     console.log("Account changed to:", chain);
     setUserAddress(chain);
  });
  }, [Moralis]);

  useEffect(() => {
    if (!isAuthenticated) router.replace("/");
    setUserAddress(user?.get("ethAddress"));
  }, [isAuthenticated, router, user]);

  return (
    <div>
      <h2>
        Logged in as {userAddress?.slice(0, 6)}...{userAddress?.slice(39)}
      </h2>
      <button onClick={handleLogout}>Logout</button>
      <Link href="/game">
        <a>Start Game!</a>
      </Link>
    </div>
  );
};
export default Dashboard;

You can have it in such way instead

  const { account } = useMoralis();

  useEffect(() => {
    console.log("Account changed to:", chain);
    setUserAddress(chain);
  }, [account]);

If you mean like this? This doesnโ€™t trigger useEffect() and address is not changed.

  useEffect(() => {
    // Account switching
    Moralis.onAccountChanged(async (chain) => {
      console.log("Account changed to:", chain);
      setUserAddress(chain);
    });
  }, [account]);

Hope Iโ€™m doing it correct :slight_smile:

No need having this. You can follow the exact one shared

Hi, Thanks for replying.
I tried using

  useEffect(() => {
    // Account switching
    Moralis.onAccountChanged(async (chain) => {
      console.log("Account changed to:", chain);
      setUserAddress(chain);
    });
  }, [account]);

I worked, But it also giving same Memory leak warning, I was thinking to use some cleanup function if that could be a thing, but canโ€™t understand how it would be implemented here :frowning:

MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 accountChanged listeners added. Use emitter.setMaxListeners() to increase limit
    at _addListener (webpack-internal:///./node_modules/events/events.js:211:15)
    at EventEmitter.addListener (webpack-internal:///./node_modules/events/events.js:227:10)
    at Function.value (webpack-internal:///./node_modules/moralis/lib/browser/MoralisWeb3.js:256:22)
    at eval (webpack-internal:///./pages/dashboard.jsx:69:17)
    at commitHookEffectListMount (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:23145:26)
    at commitPassiveMountOnFiber (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:24921:13)
    at commitPassiveMountEffects_complete (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:24886:9)
    at commitPassiveMountEffects_begin (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:24873:7)
    at commitPassiveMountEffects (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:24861:3)
    at flushPassiveEffectsImpl (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:27034:3)
    at flushPassiveEffects (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:26979:14)
    at eval (webpack-internal:///./node_modules/react-dom/cjs/react-dom.development.js:26764:9)
    at workLoop (webpack-internal:///./node_modules/scheduler/cjs/scheduler.development.js:266:34)
    at flushWork (webpack-internal:///./node_modules/scheduler/cjs/scheduler.development.js:239:14)
    at MessagePort.performWorkUntilDeadline (webpack-internal:///./node_modules/scheduler/cjs/scheduler.development.js:533:21) '\n    at Dashboard (webpack-internal:///./pages/dashboard.jsx:25:72)\n    at MoralisProvider (webpack-internal:///./node_modules/react-moralis/lib/index.esm.js:4300:23)\n    at MyApp (webpack-internal:///./pages/_app.js:13:27)\n    at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:8:20740)\n    at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/@next/react-dev-overlay/dist/client.js:8:23547)\n    at Container (webpack-internal:///./node_modules/next/dist/client/index.js:152:9)\n    at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:655:26)\n    at Root (webpack-internal:///./node_modules/next/dist/client/index.js:777:27)'

Replace everything here

With this

  useEffect(() => {
    // Account switching
    console.log("Account changed to:", chain);
    setUserAddress(chain);
  }, [account]);

What is chain here?

# Unhandled Runtime Error

ReferenceError: chain is not defined

chain is to refer to account, but not a good name in that case. Was a typo trying to use your code example. Should be account rather

  useEffect(() => {
    // Account switching
    console.log("Account changed to:", account);
    setUserAddress(account);
  }, [account]);
1 Like

Works smooth :slight_smile:
Thanks for the helpโ€ฆ