Check for duplicate in array before adding to react state

Viewed 851

I have a customInput with type select, it's onChange is running a setState.

my state object looks like this

const [upload, setUpload] = useState({
    uploadType: 'files',
    selectHeader: [],
    defaultFields: [
      {
        baseField: 'First name',
      },
      {
        baseField: 'Last name',
      },
      {
        baseField: 'Phone number',
      },
      {
        baseField: 'Company',
      },
      {
        baseField: 'Email',
      },
    ] 
  });

When the onChange runs, I am successfully adding a new object to the selectHeader array with a

{value: firstName, index: 1} 

The issue is that when a user selects a new value for a header at index 1 ( or any index for that matter) I want to check if there is duplicate in this array.

Im not sure how to do this inline with setState and cant seem to find a good thread on this example

Here is the CustomInput with type select below

<thead>
        <tr>
          {
            fileContacts.map((contact) => (
                <th scope="col" key={fileContacts.indexOf(contact)}>
        <WizardInput // this is just a fancy CustomInput at its core
        type="select"
        defaultValue={"Do not Import"}
        tag={CustomInput}
        name="selectHeader"
        id="selectHeader"
        onChange={({ target }) => {
          setUpload({...upload, selectHeader: [...upload.selectHeader, {value: target.value, index:fileContacts.indexOf(contact)}]})
          // this is adding a duplicate object if the user changes the header value twice.
        }}
        innerRef={register}
        errors={errors}
        options={['First Name', 'Last name', 'Phone', 'Email']}
      />
            </th>  
            ))}
        </tr>
      </thead>
4 Answers

Maybe you could filter out the previous one before adding in the new one.

setUpload({...upload, selectHeader: [...upload.selectHeader.filter(({value}) => value != target.value), { value: target.value, index:fileContacts.indexOf(contact) }] })

Try to use functional updates:

setUpload((upload)=>{

    if(upload.selectHeader.some(h => h.value == target.value)) return upload

    return {
        ...upload,
        selectHeader: [
            ...upload.selectHeader, 
            {
                value: target.value,
                index:fileContacts.indexOf(contact)
            }
        ]
    }
})

Example: const [arr, setArr] = React.useState([1,2,1,6,4,3,3,1]);

function rerange() {
    setArr(old => old.filter(elem => old.indexOf(elem) == old.lastIndexOf(elem)))
// returns new array eliminating the duplicates
}
Related