1

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.

3
  • Overcome what issue? What specifically isn't working as expected in the code shown? Commented Sep 1, 2022 at 16:16
  • There is no issue, but I want to add "details" instead of " const [items, setItem] = useState<string[]>([]); const [value, setValue] = useState('') const [error, setError]= useState('')" these lines..that's my issue.. Commented Sep 1, 2022 at 16:18
  • What prevents you from doing this? You can place anything you want in state, from a single value to a complex object hierarchy. What have you tried and what didn't work as expected? Commented Sep 1, 2022 at 16:19

1 Answer 1

2

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*/});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.