Creating an autogrowing textarea with React and Typescript

28 December 2023

In my 6 years career I almost never had to make an autogrowing textarea field like the ones we have in Jira or Linear (i.e. description fields) 👇

But recently, I had to make one. While there are already some posts about this, e.g. THIS post by Owen, I thought I'd post my solution, which covers a slightly different scenario.

So basically, I create a hook

export const useInputHeight = (name: string, value: string | undefined) => { const setInputHeight = useCallback(() => { const textarea: HTMLTextAreaElement | null = document.querySelector(name); if (!textarea) return; textarea.style.height = textarea.scrollHeight + "px"; }, [name]); useEffect(() => { setInputHeight(); }, [value, setInputHeight]); return setInputHeight; };

It returns a setInputHeight function that we call in our onChange function.

const setNameInputHeight = useInputHeight('textarea[name="email"]', emailValue); // ... const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { setInputHeight(); // ... other functionality };

Do you need a value argument? No, you don't, but in my case, the value was being updated on the client, so I had to adjust the field height every time it updated without me triggering the onChange event.

If that's not the case, simplify it to be

export const useInputHeight = (name: string) => { const setInputHeight = () => { const textarea: HTMLTextAreaElement | null = document.querySelector(name); if (!textarea) return; textarea.style.height = textarea.scrollHeight + "px"; }; return setInputHeight; };

That's all you'd need.

You may have also noticed that I'm not using useRef() and simply doing document.querySelector.

Would ref work? Yes, yes it should. The only reason I was using querySelector was because I was using a UI library and textarea there wasn't allowing a ref prop. So I didn't want to do all those workarounds, querySelector seemed like a great option.

Do feel free to use a ref if you'd like, after all, it IS a more 'React way' of doing things 😁👍

©2023 Rail Yard Works LTD is registered in England and Wales, no. 12126621.