skip to Main Content

I have a simple component, which should update the value of the text area when new text is dropped on it. It is correctly showing the "default" value on initial render, but is not rerendered on drop event. In the console I see the new text value and "drop!" are logged as expected. Why the component is not rerendered?

import React from "react"
import PropTypes from "prop-types"
import { useDrop } from 'react-dnd'
import { useState } from "react";

const CodeArea = (props) => {
  const [areaValue, setAreaValue] = useState("default");

  function addText(item) {
    // document.getElementById("myTextArea").value = 
    //   document.getElementById("myTextArea").value + item.text;
    console.log("drop!")
    console.log(item.text)
    setAreaValue(item.text);        
  }

  const [ , drop] = useDrop(() => ({
    accept: "block",
    drop: (item) => addText(item)
  }))

  return (
    <React.Fragment>
      <textarea
        ref={drop}
        id="myTextArea"
        name="myTextArea"
        rows="25"
        cols="50"
      >
        {areaValue}
      </textarea>
    </React.Fragment>
  )
}

CodeArea.propTypes = {
};

export default CodeArea

2

Answers


  1. try using the value of textarea attribute, like this:

    <textarea ref={drop} id="myTextArea" name="myTextArea" rows="25" cols="50" value={areaValue}/>
    Login or Signup to reply.
  2. The textarea element you are rendering is uncontrolled, so updating the areaValue state won’t update it.

    See:

    Instead of trying to render the areaValue as a child of textarea, pass is as the value prop. To allow manual editing of the text, use an onChange handler.

    Example:

    import React from "react";
    import { useDrop } from 'react-dnd';
    import { useState } from "react";;
    
    const CodeArea = () => {
      const [areaValue, setAreaValue] = useState("default");
    
      const addText = (item) => setAreaValue(item.text);
      const changeHandler = e => setAreaValue(e.target.value);
    
      const [, drop] = useDrop(() => ({
        accept: "block",
        drop: addText,
      }));
    
      return (
        <textarea
          ref={drop}
          id="myTextArea"
          name="myTextArea"
          rows="25"
          cols="50"
          value={areaValue}        // <-- control input value
          onChange={changeHandler} // <--respond to changes
        />
      );
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search