Text Area turning to div when clicked outside

Viewed 41

I am trying to create a text area with react and tailwind which I can enter text in and when I click outside of the text area it turns into a regular div displaying the text previously entered in the text area. I am working towards replacing the text area with an editor as the next step so that when I click inside the editor I can edit text and when I click outside the text shows as a div. Can someone help me?

import React, { useRef, useEffect, useState } from "react";


function DraftPage(props) {
   const [isSelected, setIsSelected] = useState(false)
   let text = "fff";
    useEffect(() => {
        if (!isSelected)
            document.addEventListener('click', handleClickOutside, true)
        else
            document.addEventListener('click', handleClickOutsideActive, true)

    },[])

    const handleClickOutside = (e) => {
        if (refOne.current!= null)
            if (refOne.current.contains(e.target)) {
                console.log("clicked inside...")
                text = e.target.value;
                setIsSelected(true);

                }
    }

    const handleClickOutsideActive = (e) => {
            if (refTwo.current!=null )
                if (isSelected && !refTwo.current.contains(e.target)) {
                    console.log("clicked outside...")
                    setIsSelected(false);
                    }
        }




    const refOne = useRef(null);
    const refTwo = useRef(null);
    const res1 = <div ref={refTwo}><textArea  placeholder={text} class="w-[750px] h-[200px] border
    border-4 border-red-400 m-10 bg-gray-100"></textArea></div>
    const res2 = <div ref={refOne}  class="w-[750px] h-[200px] border border-4 border-green-700
    bg-green-300 m-10">{text}</div>

  return <div>{isSelected ? res1 : res2}</div>
}


export default DraftPage;
1 Answers

You don't need to use useRef and outside click handlers. You can handle the onBlur event of the textarea for not selected cases, and the onClick event of the div for the selected cases.

import React, { useState } from "react";

function DraftPage(props) {
  const [isSelected, setIsSelected] = useState(false);
  const [text, setText] = useState("fff");

  const res1 = (
    <div>
      <textarea
        onBlur={() => setIsSelected(false)}
        value={text}
        onChange={(e) => setText(e.target.value)}
        className="w-[750px] h-[200px] border
    border-4 border-red-400 m-10 bg-gray-100"
      ></textarea>
    </div>
  );
  const res2 = (
    <div
      style={{ whiteSpace: "pre-line" }}
      onClick={() => setIsSelected(true)}
      className="w-[750px] h-[200px] border border-4 border-green-700
    bg-green-300 m-10"
    >
      {text}
    </div>
  );

  return <div>{isSelected ? res1 : res2}</div>;
}

export default DraftPage;

You can take a look at this sandbox for a live working example of this code.

Related