Home > front end >  React replace an element with another when clicking outside
React replace an element with another when clicking outside

Time:01-19

So I'm trying to replace a span with an input when clicked and then replace back when enter key is pressed or when the user clicked outside of it. Here's my code:

const input = useRef<HTMLInputElement>(null);
const span = useRef<HTMLSpanElement>(null);

const [ titleVisible, setTitleVisible ] = useState(true);
const [ title, setTitle ] = useState('title');

const close = (value: string) => {
    setTitle(value.trim());
    setTitleVisible(true);
}

onclick = e => {
    if (!titleVisible && e.composedPath()[0] !== input.current) {
       setTitleVisible(true);
    }
}

useEffect(() => {
    if (span.current) {
        span.current.onclick = () => {
            setTitleVisible(false);
        }
    } else {
        input.current!.value = title;
        input.current!.onkeyup = e => {
            if (e.key === 'Enter') close(input.current!.value);
        }
    }
}, [titleVisible]);
    
return (
    <div className="topInfo">
        { titleVisible ? <span ref={span}>{title}</span> : <input type="text" ref={input} /> }
    </div>
);

Thanks in advance!

CodePudding user response:

This is a way to achieve what you want

  const [isEditing, setIsEditing] = useState(false);
  const [text, setText] = useState('Click to edit');
  const inputRef = useRef(null);

  function handleClick() {
    setIsEditing(true);
  }

  function handleBlur(event) {
    setIsEditing(false);
    setText(event.target.value);
  }

  function handleKeyDown(event) {
    if (event.key === 'Enter') {
      setIsEditing(false);
      setText(event.target.value);
    }
  }

  useEffect(() => {
    if (isEditing) {
      inputRef.current.focus();
    }
  }, [isEditing]);

  return (
    <div>
      {isEditing ? (
        <input
          ref={inputRef}
          type="text"
          defaultValue={text}
          onBlur={handleBlur}
          onKeyDown={handleKeyDown}
        />
      ) : (
        <span onClick={handleClick}>{text}</span>
      )}
    </div>
  );
  • Related