Hello again! Let's continue our journey into building dApp frontends with React.
In the last lesson, we successfully integrated the @solana/wallet-adapter-react-ui package and implemented the WalletMultiButton. This provided our users with a clean, functional UI for connecting and disconnecting their wallets. While the button works, our application itself remains unaware of the wallet's state.
Today, we'll bridge that gap. This lesson focuses on how to manage and display the connected wallet's public key and connection state. We'll use a core React hook from the wallet-adapter library to access this information, allowing you to create a truly dynamic and responsive user experience based on whether a user is connected and who they are.
Accessing Wallet State with the useWallet Hook
The WalletMultiButton is a UI component. The real power for application logic comes from the useWallet hook, provided by the @solana/wallet-adapter-react package. As you know from your extensive React experience, hooks allow functional components to tap into state and lifecycle features. useWallet is our gateway to the state managed by the WalletProvider you set up earlier.
The useWallet hook returns an object containing a wealth of information and functions related to the wallet's state. For this lesson, we will focus on two of its most important properties:
connected: A boolean that istrueif a wallet is connected andfalseotherwise.publicKey: APublicKeyobject from@solana/web3.jsrepresenting the user's wallet address. It isnullif no wallet is connected.
Let's look at a practical, well-structured example of how to use this hook to build a component that reacts to the connection state.
Connect Any Website to Solana Wallet in 5 Minutes (2025 ...
The following article, 'Connect Any Website to Solana Wallet in 5 Minutes', which we looked at previously, contains a perfect example component. We will focus on the code that brings the wallet state into the React component.
Please read Step 4: Add the ConnectButton Component. Focus on the code block for the WalletConnectionDemo.tsx file. Pay close attention to how useWallet is imported and how the publicKey and connected variables are used in the JSX to conditionally render different messages.
This example clearly demonstrates the fundamental pattern:
- Import
useWallet. - Call it within your component to get the state:
const { publicKey, connected } = useWallet(); - Use these variables in your JSX to control what the user sees.
Notice the check: {connected && publicKey && ...}. This is crucial because publicKey will be null when disconnected, and attempting to use it would cause a runtime error. Also, note that to display the wallet address, you must convert the publicKey object to a string using the .toBase58() method.
Visualizing State Changes
Now let's see this in action. The following video demonstrates building a simple display that changes based on the wallet's connection status. This reinforces the concept of using a ternary operator with the wallet state.
Use The Solana Wallet Adapter (Next.js, TypeScript, Tailwind CSS) • Solana Frontend Developer Course
This video from the Helius developer course provides a clear, visual walkthrough of displaying the connection status.
Watch the segment from 00:29:48 to 00:32:34. The instructor implements a list item that displays 'Yes' or 'No' based on whether the publicKey object exists. This is a direct, practical application of the state we're discussing.
Putting It All Together
Let's synthesize what we've learned from the resources into a minimal, clear component.
import React from 'react';
import { useWallet } from '@solana/wallet-adapter-react';
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
const UserStatus = () => {
// Destructure the `connected` and `publicKey` properties from the hook
const { connected, publicKey } = useWallet();
return (
<div style={{ padding: '20px', border: '1px solid #ccc', borderRadius: '8px' }}>
{/* The connection button we added in the last lesson */}
<WalletMultiButton />
<h3 style={{ marginTop: '20px' }}>Wallet Status:</h3>
{/* Use the 'connected' boolean for a simple status display */}
<p>Connection Status: {connected ? 'Connected' : 'Disconnected'}</p>
{/*
Conditionally render the public key only if it exists.
Remember to use .toBase58() to get the string representation.
*/}
{publicKey && (
<p>Your Wallet Address: {publicKey.toBase58()}</p>
)}
{!connected && (
<p>Please connect your wallet to see your address.</p>
)}
</div>
);
};
export default UserStatus;
This UserStatus component is a self-contained example that shows the button, the connection status, and the public key, all reacting correctly as you connect and disconnect.
Test your understanding!
Imagine you wrote the following line of code without any conditional checks: <p>Address: {publicKey.toBase58()}</p>. What would happen when a user first loads the dApp before connecting their wallet, and why?
Show answer
The application would crash with a runtime error, likely TypeError: Cannot read properties of null (reading 'toBase58'). This is because on initial load, publicKey is null. The code attempts to call the .toBase58() method on null, which is not allowed. This is why a conditional check like publicKey && ... is essential for safe rendering.
Guarding Actions with Connection State
Displaying information is one thing, but more importantly, you'll need to prevent users from performing actions that require a wallet connection. The connected boolean or the existence of publicKey is your primary tool for this.
This pattern is a cornerstone of dApp development. Before attempting any on-chain interaction (like sending a transaction or fetching user-specific data), you must first verify that a wallet is connected.
The QuickNode guide we've used before has a good example of this inside a click handler.
How to Connect Users to Your dApp with the Solana Wallet ...
This guide demonstrates how to create a custom component and guard an action with a wallet connection check. This is a critical security and usability pattern.
In the article, find the sub-section titled 'Create a Click Handler'. Notice the onClick function. The very first thing it does is check if (!publicKey). This is a classic example of a 'guard clause' that prevents the rest of the function from executing if a wallet isn't connected.
This pattern ensures your application behaves predictably and provides clear feedback to the user, preventing them from running into confusing errors.
Conclusion
In this lesson, you've learned how to bring wallet awareness into your React components. This is the link between the UI and the blockchain identity of your user.
Key Takeaways:
- The
useWallethook is the primary way to access wallet state within your React components. - The
connected(boolean) andpublicKey(object or null) properties are essential for understanding the wallet's current state. - You must always check if
publicKeyexists before trying to use it, typically withpublicKey && ...or anif (publicKey)block. - To display a wallet address, you must call the
.toBase58()method on thepublicKeyobject. - The connection state is crucial for both conditionally rendering UI and for "guarding" functions that require a wallet to be connected.
You now have the skills to build a UI that intelligently adapts to the user's connection status and displays their on-chain identity.
Preview of the Next Lesson:
Now that we can get the user's public key, the next logical step is to fetch data associated with that key from the blockchain. In the next lesson, "Fetch and display the native SOL balance and SPL token balances for the connected wallet," we will use the user's public key to query the Solana network and display how much SOL they hold. This will be our first real interaction with live on-chain data.
Can't find a good explanation? Sign up and we'll make it for you
Sign up