Hone logo
Hone
Problems

React Custom Hook: useCopyToClipboard

This challenge is about building a reusable React custom hook that simplifies the process of copying text to the user's clipboard. This is a common UI pattern for sharing links, code snippets, or any other piece of text, and a dedicated hook will make it easier to implement across various components.

Problem Description

Your task is to create a custom React hook named useCopyToClipboard that provides functionality to copy a given string to the user's clipboard. The hook should expose a function to trigger the copy operation and a state variable to indicate whether the copy operation was successful.

Key Requirements:

  • The hook should accept the text to be copied as an argument.
  • The hook should return an array containing:
    • A function to initiate the copy-to-clipboard action.
    • A boolean state indicating if the last copy operation was successful.
  • The copy operation should utilize the browser's navigator.clipboard.writeText() API.
  • Handle potential errors during the copy operation gracefully.

Expected Behavior:

When the returned function is called, it should attempt to copy the provided text to the clipboard. The success state should update accordingly.

Edge Cases to Consider:

  • Browser Support: The navigator.clipboard API might not be available in all environments or older browsers. The hook should handle this gracefully.
  • Permissions: In some browsers, clipboard access might require user permission. The hook should ideally provide feedback or a way to handle this, though for this challenge, we'll focus on the API call itself.
  • Empty Text: What happens if an empty string is passed to the hook?

Examples

Example 1: Basic Usage

// In a component:
const [copyToClipboard, hasCopied] = useCopyToClipboard("Hello, world!");

// When a button is clicked:
<button onClick={copyToClipboard}>Copy Text</button>
{hasCopied && <p>Text copied!</p>}

Output:

When the button is clicked, "Hello, world!" is copied to the clipboard. The hasCopied state becomes true briefly, and then the "Text copied!" message is displayed.

Explanation: The useCopyToClipboard hook is initialized with the string "Hello, world!". The copyToClipboard function is called, which uses navigator.clipboard.writeText() to copy the string. The hasCopied state is set to true to indicate success.

Example 2: Handling Different Text

// In a component:
const [copyUrl, urlCopied] = useCopyToClipboard("https://example.com/share");

// When a button is clicked:
<button onClick={copyUrl}>Copy Link</button>
{urlCopied && <p>Link copied!</p>}

Output:

When the button is clicked, "https://example.com/share" is copied to the clipboard. The urlCopied state becomes true briefly, and then the "Link copied!" message is displayed.

Explanation: Similar to Example 1, but with a URL string.

Example 3: Error Handling (Conceptual)

Let's assume a scenario where navigator.clipboard.writeText throws an error (e.g., due to browser limitations or permissions issues).

// In a component:
const [copySensitiveData, dataCopied] = useCopyToClipboard("Sensitive Info");

// In the hook (conceptual error handling):
try {
  await navigator.clipboard.writeText(textToCopy);
  setHasCopied(true);
} catch (error) {
  console.error("Failed to copy text:", error);
  setHasCopied(false); // Ensure it's false on error
}

Output:

If an error occurs during the writeText operation, the hasCopied state (or dataCopied in this conceptual example) would remain false, and an error message would be logged to the console.

Explanation: The hook should incorporate a mechanism to catch errors and prevent the hasCopied state from being incorrectly set to true.

Constraints

  • The hook must be implemented in TypeScript.
  • The hook should not use any external libraries.
  • The navigator.clipboard.writeText() API should be the primary method for copying.
  • The hook should be a functional component hook (i.e., start with use).

Notes

  • Consider how you will handle the asynchronous nature of navigator.clipboard.writeText().
  • Think about the initial state of the success flag.
  • A short delay before resetting the success state might improve the user experience, allowing them to see the confirmation message. You might want to implement this as an optional feature or a consideration for a more advanced version of the hook.
  • For simplicity in this challenge, you can assume that if navigator.clipboard.writeText is available, it will generally work without explicit permission prompts being handled within the hook itself. The focus is on the core logic.
Loading editor...
typescript