Home > Blockchain >  Textarea component which shows the count of written characters in React updates the value only after
Textarea component which shows the count of written characters in React updates the value only after

Time:12-23

Having the following component:

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;

This component returns a textarea where the user can write an input, also it shows the current count of introduced characters.

It is used inside a Modal, when first open the modal, no matter how much text is written, the value shown is 0 (value of count). If the modal is closed and opened again, the value is updated with the count of the text introduced before.

Is there a way to update the count in real time when writting?

CodePudding user response:

You can do it simply like this,

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;

or if you get the value from props,

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

CodePudding user response:

This is a easy task. You can attach an onInput to the textarea and use setCount(event.target.value.length} to update the count.

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

CodePudding user response:

You should not get the component value using the document. React has a virtual Dom and "thinking in React", the best way to do it, would be taking the value you pass to the 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;
  • Related