Home  >  Q&A  >  body text

Add event listener to specific textarea element

I'm working on a project in Next.js13 and I'm trying to create a custom textarea component. I want this component to add an event listener to itself (allowing it to automatically adjust its height as the user types). Here is the part of the code relevant to this problem:

const textarea = (
    <textarea 
        id={id}
        className={styles.input} 
        {...fieldProps} /> 
);

textarea.addEventListener("input", function(e){
    this.style.height = "auto";
    this.style.height = this.scrollHeight + "px";
})

return (
    {textarea}
)

This code generates the errors "TypeError: textarea.addEventListener is not a function " and "Property 'addEventListener' does not exist on type 'Element'. " < /p>

How do I add this event listener to the text area created by this component?

Limitations and previously attempted solutions

  1. I want the user to be able to specify the id (but not required to do so), so I can't use document.getElementById().

  2. Rewriting the addEventListener line as follows eliminates the "Property 'addEventListener' does not exist on type 'Element' ", but will result in "TypeError: textarea.addEventListener is not a function< /strong>"is still:

    (textarea as unknown as HTMLTextAreaElement).addEventListener("input", function(e){
        this.style.height = "auto";
        this.style.height = this.scrollHeight + "px";
    })
  3. Using document.getElementsByTag('textarea') and then looping through all returned textareas and adding an event listener does work. However, if I have multiple textareas on a page, this seems to add the event listener twice. Let's say there is a text area on the page that is part of a different component and I don't want to add this event listener to it.

P粉697408921P粉697408921276 days ago516

reply all(2)I'll reply

  • P粉949190972

    P粉9491909722024-01-18 00:46:33

    In React, you cannot add event listeners directly to elements created in JSX as you can with normal JavaScript. Instead, you should handle events the React way by using the onChange attribute on the textarea element.

    TEXTAREA_COMPONENT.js

    import React, { useState } from 'react';
    
    const CustomTextarea = ({ id, ...fieldProps }) => {
      const [value, setValue] = useState('');
      const [height, setHeight] = useState('auto');
    
      const handleChange = (e) => {
        setValue(e.target.value);
        setHeight('auto');
        setHeight(e.target.scrollHeight + 'px');
      };
    
      return (