Creating a custom useCopyToClipboardEffect hook for handling side effects related to clipboard interactions

Handling side effects related to clipboard interactions, such as copying text to the clipboard, is a common task in web development. In this blog post, we will walk through the process of creating a custom React hook called useCopyToClipboardEffect that simplifies this process and can be easily reused across different components.

Table of Contents

Introduction

Copying text to the clipboard involves a series of steps including creating a temporary textarea element, manipulating the DOM, and executing the copy command. The process can be complex and repetitive when used in multiple components. By creating a custom hook, we can encapsulate the logic and reuse it across multiple components in a more organized manner.

Prerequisites

Before we dive into the implementation, make sure you have the following prerequisites in place:

Implementation

Let’s start by writing the custom hook useCopyToClipboardEffect. Here’s an example implementation using TypeScript:

import { useEffect, useCallback, useRef } from 'react';

const useCopyToClipboardEffect = (text: string): [boolean, () => void] => {
  const textareaRef = useRef<HTMLTextAreaElement | null>(null);
  const [isCopied, setIsCopied] = useState(false);

  const copyToClipboard = useCallback(() => {
    if (textareaRef.current) {
      textareaRef.current.select();
      document.execCommand('copy');
      setIsCopied(true);
    }
  }, []);

  useEffect(() => {
    textareaRef.current = document.createElement('textarea');
    document.body.appendChild(textareaRef.current);
    textareaRef.current.style.display = 'none';

    return () => {
      document.body.removeChild(textareaRef.current);
    };
  }, []);

  return [isCopied, copyToClipboard];
};

export default useCopyToClipboardEffect;

Let’s go through the implementation step-by-step:

  1. Import the necessary React hooks, useEffect, useCallback, and useRef.
  2. Create a constant called textareaRef using the useRef hook. This will be used to reference the dynamically created textarea element.
  3. Create a state variable isCopied and a setter function setIsCopied using the useState hook. This will keep track of whether the copy operation was successful or not.
  4. Define a copyToClipboard function using the useCallback hook. This function selects the contents of the textarea, executes the copy command, and sets the isCopied state to true.
  5. Use the useEffect hook to create the textarea element when the component mounts. We also hide the textarea by setting its style to display: none.
  6. Remove the dynamically created textarea element when the component unmounts. This is done in the cleanup function returned by useEffect.
  7. Return the isCopied state variable and the copyToClipboard function from the custom hook.

Usage

Now that we have our custom hook, let’s see how we can use it in a component. Here’s a simple example of a button that copies a given text to the clipboard:

import React from 'react';
import useCopyToClipboardEffect from './useCopyToClipboardEffect';

const CopyToClipboardButton = ({ text }) => {
  const [isCopied, copyToClipboard] = useCopyToClipboardEffect(text);

  return (
    <div>
      <button onClick={copyToClipboard}>Copy to Clipboard</button>
      {isCopied && <p>Text copied to clipboard!</p>}
    </div>
  );
};

export default CopyToClipboardButton;

In this example, we pass the text we want to copy as a prop to the useCopyToClipboardEffect hook. We then destructure the isCopied state variable and the copyToClipboard function from the hook’s return value. When the button is clicked, the copyToClipboard function is called, which triggers the copy operation. The isCopied state variable is used to conditionally render a success message.

Conclusion

Creating a custom useCopyToClipboardEffect hook allows us to encapsulate the complex logic related to clipboard interactions and reuse it across different components. This simplifies the code and improves the maintainability of our React applications. By following this guide, you should now have a good understanding of how to create a custom hook for handling side effects related to clipboard interactions.

References