Max SchmittMS
18th December 2022

React: How to Create an Autogrowing Textarea

An autogrowing textarea is a textarea element that automatically adjusts its height to the number of lines the user entered.

Here is a textarea component written for React that automatically adjusts its height no matter if it's controlled or uncontrolled.

Usage

<Textarea autoHeight rows={4} />

Implementation

interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
autoHeight?: boolean
}
function Textarea({
value: valueFromProps,
onChange: onChangeFromProps,
defaultValue,
autoHeight = false,
rows: rowsFromProps = 3,
...rest
}: TextareaProps) {
// Determine if component is used in a controlled or uncontrolled
// fashion.
const isControlled = typeof valueFromProps != 'undefined'
const hasDefaultValue = typeof defaultValue != 'undefined'
const [internalValue, setInternalValue] = useState(
hasDefaultValue ? defaultValue : ''
)
// If component is controlled, take the value from the props,
// otherwise take it from the value we track ourselves.
const value = isControlled ? valueFromProps : internalValue
// The rows attribute is what will determine the height of our
// textarea. Notice how we only automatically determine the
// rows attribute if props.autoHeight is true. In this case
// we also use props.rows to set the minimum number of rows.
const rows = autoHeight
? Math.max(rowsFromProps, String(value).split('\n').length)
: rowsFromProps
// This a custom onChange handler that reports any changes
// to props.onChange and also updates our internal value
// in case the component is uncontrolled.
const onChange = useCallback<React.ChangeEventHandler<HTMLTextAreaElement>>(
(e) => {
if (onChangeFromProps) {
onChangeFromProps(e)
}
if (!isControlled) {
setInternalValue(e.target.value)
}
},
[isControlled, onChangeFromProps]
)
return <textarea rows={rows} value={value} onChange={onChange} {...rest} />
}

View the demo on CodeSandbox.

Image of my head

About the author

Hi, I’m Max! I'm a fullstack JavaScript developer living in Berlin.

When I’m not working on one of my personal projects, writing blog posts or making YouTube videos, I help my clients bring their ideas to life as a freelance web developer.

If you need help on a project, please reach out and let's work together.

To stay updated with new blog posts, follow me on Twitter or subscribe to my RSS feed.