next.js 向特定TextArea元素添加EventListener

wbgh16ku  于 2023-08-04  发布在  其他
关注(0)|答案(2)|浏览(123)

我正在Next.js13中处理一个项目,并尝试创建一个自定义文本区域组件。我想让这个组件添加一个事件侦听器到它自己(允许自动调整它的高度,因为用户键入)。以下是与此问题相关的代码部分:

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}
)

字符串
此代码将生成错误“TypeError:textarea.addEventListener不是函数”和“属性”addEventListener“在类型”Element“上不存在。
如何将此事件侦听器仅添加到该组件创建的文本区域中?

约束和以前尝试的解决方案

1.我希望用户能够指定id(但不要求如此),因此我不能使用document.getElementById()
1.将addEventListener行重写为以下内容可消除“属性'addEventListener'不存在于类型'Element'上”,但会消除“TypeError:textarea.addEventListener不是一个函数”仍然存在:

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


1.使用document.getElementsByTag('textarea'),然后遍历所有返回的textareas并添加事件侦听器确实有效。但是,如果我在一个页面上有多个textareas,这似乎是添加了两次事件侦听器。我可以假设页面上有一个文本区域,它是另一个组件的一部分,我不希望将此事件侦听器添加到该组件中。

9o685dep

9o685dep1#

如果你愿意使用一个库而不是自己实现这个功能,有一个很棒的库叫做react-textarea-autosize
如果你想自己实现它,你仍然可以使用这个repo作为指导。

kq0g1dla

kq0g1dla2#

在React中,你不能像使用vanilla JavaScript那样直接向JSX中创建的元素添加事件侦听器。相反,你应该使用React的方式来处理事件,在textarea元素上使用onChange prop。

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 (
    <textarea
      id={id}
      className={styles.input}
      value={value}
      onChange={handleChange}
      style={{ height }}
      {...fieldProps}
    />
  );
};

export default CustomTextarea;

字符串

APP.js

import React from 'react';
import CustomTextarea from './path/to/CustomTextarea';

const App = () => {
  return (
    <div>
      <CustomTextarea id="your-textarea" />
      {/* other content */}
    </div>
  );
};

export default App;

相关问题