显示 React 中写入字符数的 Textarea 组件仅在重新加载后更新值

Posted

技术标签:

【中文标题】显示 React 中写入字符数的 Textarea 组件仅在重新加载后更新值【英文标题】:Textarea component which shows the count of written characters in React updates the value only after reload 【发布时间】:2022-01-24 01:09:25 【问题描述】:

具有以下组件:

import React,  useEffect, useState  from 'react';

import  TextareaTestIds  from '../utils/test-ids';

export interface TexareaProps extends React.TextareahtmlAttributes<HTMLTextAreaElement> 
  maxLength?: number;
  id: string;


export function Textarea( id, maxLength = 200, ...props : TexareaProps) 
  const test = id;
  const [count, setCount] = useState(0);
  useEffect(() => 
    const refElement = document.getElementById(test) as HTMLTextAreaElement;
    if (refElement) 
      setCount(refElement.value.length);
    
  , [test]);

  return (
    <div>
      count
      <textarea
        id=id
        maxLength=maxLength
        ...props
      ></textarea>
    </div>
  );


export default Textarea;

该组件返回一个文本区域,用户可以在其中编写输入,还显示当前引入的字符数。

在Modal内部使用,第一次打开modal时,无论写多少文字,显示的值都是0(count的值)。如果模态框关闭并再次打开,则该值会更新为之前引入的文本的计数。

有没有办法在写的时候实时更新计数?

【问题讨论】:

为什么不直接从文本区取值,直接统计呢? useEffect 总是在组件渲染之后运行。可以获取prop值或者defaultValue和count。 你能举个例子吗?我不确定我明白了 (value || defaultValue).length 【参考方案1】:

这样就可以了,

import React from "react";

export interface TexareaProps
  extends React.TextareaHTMLAttributes<HTMLTextAreaElement> 
  maxLength?: number;
  id: string;


export const Textarea = React.forwardRef(
  ( id = "my-id", maxLength = 200, ...props : TexareaProps) => 
    const [value, setValue] = useState("");

    const count = value.length;
    return (
      <div className="relative flex flex-col">
        count
        <textarea
          ...props
          value=value
          maxLength=maxLength
          onChange=(event) => setValue(event.target.value)
        ></textarea>
      </div>
    );
  
);

export default Textarea;

或者如果你从道具中获得价值,

export const Textarea = React.forwardRef(
  ( id = "my-id", maxLength = 200, ...props : TexareaProps) => 
    
    const count = props.value.length;
    return (
      <div className="relative flex flex-col">
        count
        <textarea
          ...props
          value=value
          maxLength=maxLength
        ></textarea>
      </div>
    );
  
);

【讨论】:

他不需要在组件中有状态。他可以从 ...props 中获取价值 不管用,一直显示0,即使重新打开modal 我认为你的 Modal 有问题 :)【参考方案2】:

这是一项简单的任务。您可以将onInput 附加到文本区域并使用setCount(event.target.value.length 更新计数。

https://jsfiddle.net/sean7777/Lvztbyuc/20/

【讨论】:

我收到一条错误消息:“EventTarget”类型上不存在属性“值”。 @LeoMessi 这是打字稿错误。我在下面添加了一条评论,说明了你可以如何做到这一点。第 12 行(未测试) 评论可见吗? 是的,评论是可见的。 不是..也许你没有把它保存在小提琴上【参考方案3】:

您不应该使用文档获取组件值。 React 有一个虚拟 Dom 并且“在 React 中思考”,最好的方法就是将你传递给 Textarea 的值。

 export const Textarea = ( maxLength = 200, value = "", ...props : TexareaProps) => 
 
  
   return (
      <div className="relative flex flex-col">
       value.length
      <textarea
        ...props
        value=value
        maxLength=maxLength
       ></textarea>
    </div>
      );
     
  );
  export default Textarea;

【讨论】:

我收到此错误:类型' onChange: ChangeHandler; 中缺少属性'value' onBlur:更改处理程序;参考:RefCallBack;名称:字符串; id:字符串;标签:字符串 |不明确的;容器类:字符串; ' 但在类型 'TexareaProps' 中是必需的。 是否需要以不同于模态的方式发送?我的意思是组件在哪里使用,,这里应该放什么?

以上是关于显示 React 中写入字符数的 Textarea 组件仅在重新加载后更新值的主要内容,如果未能解决你的问题,请参考以下文章

如何在TextArea里实现换行

将 REACT 组件渲染为 HTML 字符串以复制或添加到 textarea

使用 jquery 将选择器元素的 html 写入 textarea

React:将文本附加到 TextArea

使用 jQuery 将元素写入 textarea

手动写入后无法使用 javascript 更新 textarea