DEV Community

Cover image for Creating an autogrowing textarea with React and Typescript
Nikita Kakuev
Nikita Kakuev

Posted on • Originally published at railyard.works

Creating an autogrowing textarea with React and Typescript

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;
};
Enter fullscreen mode Exit fullscreen mode

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
};
Enter fullscreen mode Exit fullscreen mode

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;
};
Enter fullscreen mode Exit fullscreen mode

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 😁👍

Top comments (0)