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.