Connecting MetaMask to React — the real way
Network validation, chain switching, event listeners, and disconnection handling. The production-grade wallet connection pattern.
Every Web3 tutorial shows you this:
One line. It works. Tutorial ends.
Then you ship to production and discover: users are on the wrong network. Users switch accounts mid-session. Users disconnect and your UI shows stale data. MetaMask throws errors your code doesn't handle.
The tutorial gave you the hello world of wallet connection. This lesson gives you the production version.
1. The Story: The Wrong Network Disaster
During ChainElect's first live test, we sent the link to 30 developers. Within 5 minutes, three of them reported that voting was broken. The error: execution reverted.
The contract worked. The code was fine. But all three users were on Ethereum Mainnet — not Polygon Amoy. Our contract doesn't exist on Mainnet. Every call was hitting a void and reverting.
The naive connection code had no network check:
We needed the app to detect the wrong network and automatically prompt the user to switch — or do it for them.
2. The Visual: The Production Connection Flow
[!TIP] VISUAL TRIGGER FOR FRONTEND: Animate this as a stepped state machine — each step highlights as the connection progresses. Failures at any step show a specific error state with a clear user action (install MetaMask, switch network, approve connection).

3. Technical Explanation: The Production Connection Pattern
Here is the full, production-grade wallet connection from ChainElect, with network validation and event listeners:
The key additions vs the naive version:
- Chain ID validation — detect wrong network before allowing interaction
- Automatic chain switching —
wallet_switchEthereumChainprompts the user to switch - Chain addition fallback — if the chain isn't added yet,
wallet_addEthereumChainadds it - Event listeners —
accountsChangedandchainChangedprevent stale state after MetaMask changes
The wallet_switchEthereumChain and wallet_addEthereumChain methods only work in MetaMask and MetaMask-compatible wallets (like Coinbase Wallet). If you're building for WalletConnect or other wallet protocols, you'll need a library like wagmi or RainbowKit that abstracts these calls across wallet providers. In Track 4, we replace this entire pattern with Account Abstraction, eliminating the chain management problem entirely.
The Missing Event Listener Trap:
If you don't listen to accountsChanged, users who switch MetaMask accounts mid-session will have your UI showing the old account while MetaMask is signing transactions with the new one. This causes transactions to be sent from the wrong address — a confusing, hard-to-diagnose bug. Always register account change listeners immediately after connection.
In the ChainElect Conn_web.jsx source file, find where the chainChanged event listener is registered. What does the handler do when the chain changes? Now think about a better approach than window.location.reload() — what would you show the user instead of a full page reload?
Was this lesson helpful?
Let us know what you think of this specification. (submitting anonymously)
