Typescript: How to update the state

Viewed 32

In my project, I have an email field to implement using the chip component. But I am facing a problem here, first time, when I paste multiple email values it gets inserted into the field, but second time when I copy some other values and paste them into the field, it replaces the previous values.

In first time:

enter image description here

Secnod time when I paste "abc4@abc.com" :

enter image description here

previous values replace with the current value.

import Chip from "@material-ui/core/Chip";
import TextField from "@material-ui/core/TextField";
import React, { useRef, useState } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

export const TagActions = () => {
  const [items, setItem] = useState<string[]>([]);
  const [value, setValue] = useState("");
  const [error, setError] = useState("");
  const divRef = useRef<HTMLDivElement>(null);
  const [flag, setFlag] = useState(false);

  const handleDelete = (item: any) => {
    console.log("handleDelete", item);
    const result = items.filter((i) => i !== item);
    setItem(result);
  };

  const handleItemEdit = (item: any) => {
    console.log("handleItemEdit", item);
    const result = items.filter((i) => i !== item);
    setItem(result);
    setValue(item);
    console.log("value", value);
  };

  const handleKeyDown = (evt: any) => {
    if (["Enter", "Tab", ","].includes(evt.key)) {
      evt.preventDefault();

      var test = value.trim();

      if (test && isValid(test)) {
        items.push(test);
        setValue("");
      }
    }
  };

  const isValid = (email: any) => {
    let error = null;

    if (isInList(email)) {
      error = `${email} has already been added.`;
    }

    if (!isEmail(email)) {
      setFlag(true);
      // error = `${email} is not a valid email address.`;
    }

    if (error) {
      setError(error);

      return false;
    }

    return true;
  };

  const isInList = (email: any) => {
    return items.includes(email);
  };

  const isEmail = (email: any) => {
    return /[\w\d\.-]+@[\w\d\.-]+\.[\w\d\.-]+/.test(email);
  };

  const handleChange = (evt: any) => {
    setValue(evt.target.value);
    // setError("")
  };

  const handlePaste = (evt: any) => {
    evt.preventDefault();

    var paste = evt.clipboardData.getData("text");
    console.log("pppp", paste);
    var emails = paste.match(/[\w\d\.-]+@[\w\d\.-]+\.[\w\d\.-]+/g);

    if (emails) {
      console.log("inside if", emails);
      var toBeAdded = emails.filter((email: any) => !isInList(email));

      setItem(toBeAdded);
    }

  };

  return (
    <>
      <div>
        <TextField
          id="outlined-basic"
          variant="outlined"
          InputProps={{
            startAdornment: items.map((item) => (
              <Chip
                className={!isEmail(item) ? "chip-tag-error" : "chip-tag"}
                key={item}
                tabIndex={-1}
                label={item}
                onDelete={() => handleDelete(item)}
                onClick={() => handleItemEdit(item)}
              />
            )),
          }}
          ref={divRef}
          value={value}
          placeholder="Type or paste email addresses and press `Enter`..."
          onKeyDown={(e) => handleKeyDown(e)}
          onChange={(e) => handleChange(e)}
          onPaste={(e) => handlePaste(e)}
        />
      </div>

      {error && <p className="error">{error}</p>}
    </>
  );
};


I am a beginner in react typescript. Please give me a solution to solve this situation.

1 Answers

Append to the list instead of overwriting it like

setItem(i => [...i, ...toBeAdded]);
Related