Home > Mobile >  Reactjs: How to replace the useState?
Reactjs: How to replace the useState?

Time:09-02

In my project, using useState to initialize values, I am a beginner in React TypeScript. So I don't know how to replace them with interface or type. I referred some documentation to solve this but didn't get the expected result.

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

interface details{
    value: string;
    emails: Array<string>;
    error?: string | null;
    item?:string;
  }
  

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

    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)) {
          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");
        var emails = paste.match(/[\w\d\.-] @[\w\d\.-] \.[\w\d\.-] /g);
    
        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
                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>}
        </>
      );
}


Currently, setItem, setValue, and setError are used to update corresponding values. So how about using "details" instead?, Please give me some suggestions to overcome this issue.

CodePudding user response:

You can work with the entire object like that:

interface IDetails {
    value: string;
    emails: Array<string>;
    error?: string | null;
    item?:string;
  }

const [details, setDetails] = useState<IDetails>({/*Your initial state here*/});
  • Related