React

Creating a Textarea with dynamic height using React

Creating a Textarea with dynamic height using React

Resizing textarea fields is a widely utilized feature, particularly on social networks. By default, the form remains at a fixed size, which can only be adjusted using the rows attribute set to an integer value. However, the goal is to provide a seamless experience for the user, so that the text remains fully visible without the need for scrolling, regardless of its size.

To make the textarea resizable, we need to make changes to its height based on the amount of text entered. There are many solutions on the Internet, but I will share with you the most effective and simplest one that I use myself.

Setting up a hook

We will start by creating a hook named useAutosizeTextArea that will handle the resizing of the textarea. To do this, we will be using the useEffect hook from React.

Here's the code example:

import { useEffect } from 'react'

// Updates the height on value update.
export const useAutosizeTextArea = (textAreaRef: HTMLTextAreaElement | null, value: string) => {
  useEffect(() => {
    // make sure that textAreaRef exists
    if (textAreaRef) {
      // We need to reset the height first to get the correct scrollHeight for the textarea
      textAreaRef.style.height = '0px'
      const { scrollHeight } = textAreaRef

      // Now we set the height directly
      textAreaRef.style.height = `${scrollHeight}px`
    }
  }, [textAreaRef, value])
}

The hook takes two parameters: textAreaRef and a value. textAreaRef is a reference to the textarea element.

In the hook, we use the useEffect to track changes. Whenever the value changes, the height of the textarea is updated.

Creating The Textarea Component

Next, we will create a Textarea component that uses the hook we created earlier. In our case Textarea component takes several props, including a placeholder, value, onChange, and label.

Here's the code for this component (just the most basic example):

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

  return (
    <>
      {label && (
        <label className={styles.label} htmlFor="textarea-id">
          {label}
        </label>
      )}
      <textarea
        ref={textAreaRef}
        id="textarea-id"
        className={styles.textarea}
        onChange={onChange}
        placeholder={placeholder}
        value={value}
        rows={3}
      />
    </>
  )
}

In the this component, we create a reference to the textarea element using useRef. Then we pass this reference to the useAutosizeTextArea hook, along with the value.

The rest of the code is just standard React stuff.

That's all, folks!

Small, but effective!

In this tutorial, we learned how to create a resizable textarea in React. We created a hook named useAutosizeTextArea that updates the height of the textarea based on the amount of text entered. We also created a Textarea component that uses that hook to make the textarea resizable.

By using the useEffect hook and the scrollHeight property, we were able to make the textarea dynamically resize based on the amount of text entered by the user. This is a useful technique to have in your toolkit when building user-friendly and responsive UI components in React.

A blog for self-taught engineers

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