React

Creating a Resizable Textarea with Dynamic Height in React

Creating a Resizable Textarea with Dynamic Height in React

Resizable textarea fields are essential for enhancing user experience, especially in modern web applications like social networks. By default, text areas have a fixed size, which can only be adjusted using the rows attribute set to an integer value. A dynamic height textarea allows users to see all their input without scrolling, thereby improving interaction quality.

In this tutorial, we will explore how to create a textarea that automatically adjusts its height based on the content entered by the user—commonly referred to as "dynamic textarea height" in React applications. We will utilize the custom hook useAutosizeTextArea to achieve this functionality effectively.

Setting Up the Hook for Auto-Resizing Textareas

We will create a custom hook named useAutosizeTextArea that dynamically updates the height of the textarea. This hook will leverage React's useEffect to monitor changes in the textarea’s value.

Here’s how you implement it:

import { useEffect, useRef } from 'react';

// Custom hook for dynamic height adjustment
export const useAutosizeTextArea = (textAreaRef: HTMLTextAreaElement | null, value: string) => {
  useEffect(() => {
    if (textAreaRef) {
      // Reset height to auto for accurate scrollHeight computation
      textAreaRef.style.height = 'auto';
      textAreaRef.style.height = `${textAreaRef.scrollHeight}px`;
    }
  }, [textAreaRef, value]);
};

Explanation

In this hook:

  • textAreaRef: A reference to the textarea DOM element.
  • value: The current value of the textarea.

The useEffect hook resets the height and then sets it to match the scrollHeight every time the value changes, ensuring that all content is visible without scrolling.

Creating the Textarea Component with Auto Height

Next, let's build a reusable Textarea component in React that utilizes our custom hook. This component will accept several props, such as placeholder, value, onChange, and label.

Here's how you can define the Textarea component:

import React, { useRef } from 'react';

interface TextAreaProps {
  placeholder?: string;
  value: string;
  onChange: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
  label?: string;
}

export function Textarea({ placeholder = '', value = '', onChange, label }: TextAreaProps) {
  const textAreaRef = useRef<HTMLTextAreaElement>(null);
  useAutosizeTextArea(textAreaRef.current, value);

  return (
    <>
      {label && (
        <label className="textarea-label" htmlFor="textarea-id">
          {label}
        </label>
      )}
      <textarea
        ref={textAreaRef}
        id="textarea-id"
        className="textarea"
        onChange={onChange}
        placeholder={placeholder}
        value={value}
        rows={1} // Start with one row
      />
    </>
  );
}

Component Breakdown

  1. useRef: Creates a mutable reference to store the textarea DOM element.
  2. Dynamic Height Behavior: The useAutosizeTextArea hook is invoked with the textarea reference and its value.
  3. Props: Accepts placeholder, value, onChange, and an optional label for accessibility.

Conclusion

Congratulations! You’ve learned how to create a resizable textarea with dynamic height in React. Using our useAutosizeTextArea custom hook, we ensured that users can type freely without worrying about their input being cut off or requiring cumbersome scrolling.

This technique not only enhances user experience but also contributes to building user-friendly and responsive UI components in your React applications. Consider utilizing similar techniques across other input fields for improved interactivity.

By mastering these practices, you're equipped to develop high-quality software that caters to modern user expectations, ultimately leading to better engagement and satisfaction.

A blog for self-taught engineers

Сommunity is filled with like-minded individuals who are passionate about learning and growing as engineers.