Hone logo
Hone
Problems

React useCopyToClipboard Hook

This challenge asks you to create a reusable React hook, useCopyToClipboard, that provides functionality to copy text to the user's clipboard. This hook is useful for providing a convenient way to copy data (like generated code snippets, URLs, or other relevant information) directly from your React application to the clipboard with a simple API.

Problem Description

You need to implement a useCopyToClipboard hook in TypeScript. This hook should accept a string as input (the text to be copied) and provide a function that, when called, copies the provided text to the user's clipboard. The hook should also manage the state to indicate whether the copy operation was successful or if an error occurred.

Key Requirements:

  • Input: The hook should accept a text string as an argument.
  • Copy Function: The hook should return a function, copyToClipboard, that, when invoked, attempts to copy the text to the clipboard.
  • State Management: The hook should maintain three state variables:
    • loading: A boolean indicating whether the copy operation is in progress. Initial value should be false.
    • success: A boolean indicating whether the copy operation was successful. Initial value should be false.
    • error: A string containing an error message if the copy operation failed, or null if no error occurred.
  • Error Handling: The hook should handle potential errors during the copy operation (e.g., the user denies clipboard access) and update the error state accordingly.
  • Reset State: After a successful copy or an error, the loading state should be set to false.

Expected Behavior:

  1. When copyToClipboard is called:
    • The loading state should be set to true.
    • The hook should attempt to copy the text to the clipboard using the navigator.clipboard.writeText() method.
    • If the copy is successful, the success state should be set to true, and error to null.
    • If the copy fails (e.g., due to permissions issues), the error state should be set to an appropriate error message, and success to false.
    • The loading state should be set to false in either case.
  2. The hook should return an object containing the copyToClipboard function, the loading state, the success state, and the error state.

Edge Cases to Consider:

  • Browser Support: navigator.clipboard might not be supported in all browsers. The hook should gracefully handle this situation (e.g., by providing a fallback mechanism or an error message). For this challenge, assume modern browser support.
  • Permissions: The user might deny clipboard access. The hook should handle this scenario and update the error state accordingly.
  • Empty Text: The hook should handle the case where the input text is an empty string. Copying an empty string is valid, so success should be true and error should be null.

Examples

Example 1:

Input: text = "Hello, world!"
Output: { copyToClipboard: function, loading: false, success: false, error: null }
Explanation: Initially, loading is false, success is false, and error is null.

Example 2:

Input: text = "https://example.com" and copyToClipboard() is called.  Copy succeeds.
Output: { copyToClipboard: function, loading: false, success: true, error: null }
Explanation: After a successful copy, loading is false, success is true, and error is null.

Example 3:

Input: text = "Some text" and copyToClipboard() is called. User denies clipboard access.
Output: { copyToClipboard: function, loading: false, success: false, error: "Clipboard access denied." }
Explanation: After a failed copy due to permissions, loading is false, success is false, and error contains an appropriate message.

Constraints

  • The hook must be written in TypeScript.
  • The hook should use navigator.clipboard.writeText() for copying.
  • The hook should handle potential errors gracefully.
  • The hook should be reusable and independent of any specific component.
  • The hook should not rely on external libraries.

Notes

  • Consider using try...catch blocks to handle potential errors during the copy operation.
  • Think about how to provide a user-friendly error message when clipboard access is denied.
  • The copyToClipboard function should be a stable reference (i.e., it shouldn't be recreated on every render unless the text prop changes). Use useCallback to achieve this.
  • The loading, success, and error states should be managed using useState.
  • Focus on creating a clean, well-documented, and robust hook.
Loading editor...
typescript