skip to Main Content

The code sets the textCount to match the input onChange, but I need textCount to also be set to the value that comes from inside of App() from name.

import React, { useState } from "react";

function Textarea(props) {
  const [textCount, settextCount] = useState(0);

  const recalculate = (e) => {
    settextCount(e.target.value.length);
  };

  return (
    <>
      <textarea
        type="text"
        onChange={(e) => {
          recalculate(e);
          props.onChange(e);
        }}
      />
      <p>{textCount}/5</p>
    </>
  );
}
export default Textarea;
const App = (props) => {
const {name} = props.stateData;
  const change = async (e) => {
    props.changevalue(e);
  };
  return (
    <>
      <Textarea value={name} onChange={change} />
    </>
  );
};

3

Answers


  1. The value attribute on form elements will override the value in the DOM. If you want to specify the initial value, but leave subsequent updates uncontrolled, you can specify a defaultValue attribute instead of value.

    <textarea defaultValue={name} onChange={change} />
    
    Login or Signup to reply.
  2. You can add a state inside your Textarea component and set it to its initial value, also initialize the count corresponding:

      const [textCount, settextCount] = useState(props.value.length);
      const [textValue, setTextValue] = useState(props.value);
    

    Then use the textvalue inside the textarea:

      <textarea
        type="text"
        value={textValue}
        onChange={(e) => {
          recalculate(e);
          props.onChange(e);
          setTextValue(e.target.value)
        }}
      />
    

    if that is what your looking for here’s a working sandbox

    Edit: add the improved sandbox from comments

    improved version from @Leland

    Login or Signup to reply.
  3. You don’t need to have state for textCount since the Textarea component is going to be re-rendered any time it receives a new value, therefore we can calculate the length of the value while rendering.

    Also, the <p> tag has to be outside the <textarea> element, and the recalculate() function doesn’t seem to be necessary in this case since we can get the length just by reading the length property from the value.

    export default function App() {
      const [textValue, setTextValue] = useState("initialValue");
      return (
        <div className="App">
          <Textarea value={textValue} onChange={setTextValue}/>
        </div>
      );
    }
    
    export function Textarea(props) {
      return (
        <>
          <textarea value={props.value} onChange={(e) => {
            props.onChange(e.target.value)
          }}
          ></textarea>
          <p>textCount: {props.value.length}</p>
        </>
      )
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search