Search code examples
javascriptreactjsrecoiljs

Delete an element from an array (RecoilJS)


I have a form where I put a float value (1.1, 1.2, 1.9 and so on) and I want to store a bunch of them inside an array on an atom:

import { atom } from 'recoil';

export const valueState = atom({
    key: 'values',
    default: []
});

Whenever I write a value and it's checked that it's a double, the value gets added to valueState, however, I want to make it so if that the value I write on the form gets deleted, it also deletes the value from the valueState array. I tried by using pop, however, if I do so the program crashes. How can I do it then?

import { valueState as valueStateAtom } from '../../atoms/Atoms';
import { useSetRecoilState } from 'recoil';
const setValue = useSetRecoilState(valueStateAtom);


// The function that handles the onChange event of the form
const setNewValue = (v) => {
   if (v !== '') {
      const valueNumber = parseFloat(v);
      if (!isNaN(valueNumber)) {
         setPageValueChanged(true);
         pageValue = valueNumber;
         // The value gets added to valueState
         setValue((prev) => prev.concat({ valueNumber, cardID }));
      } else {
          setPageValueChanged(false);
      }
   } else {
       setPageValueChanged(false);
       // Delete v from the atom array here
    }
};

Solution

  • pop did not work for you because it does not return a new array (state immutability)

    I think you can do a trick with filter. For example

    setValue((prev) => prev.filter((value, index) => index !== prev.length - 1));
    

    Full code

    import { valueState as valueStateAtom } from '../../atoms/Atoms';
    import { useSetRecoilState } from 'recoil';
    const setValue = useSetRecoilState(valueStateAtom);
    
    
    // The function that handles the onChange event of the form
    const setNewValue = (v) => {
       if (v !== '') {
          const valueNumber = parseFloat(v);
          if (!isNaN(valueNumber)) {
             setPageValueChanged(true);
             pageValue = valueNumber;
             // The value gets added to valueState
             setValue((prev) => prev.concat({ valueNumber, cardID }));
          } else {
              setPageValueChanged(false);
          }
       } else {
           setPageValueChanged(false);
           setValue((prev) => prev.filter((value, index) => index !== prev.length - 1));
        }
    };
    

    One more feedback, your concat is seemingly incorrect. It's expecting to have an array param but you passed an object. The modification can be

    setValue((prev) => prev.concat([{ valueNumber, cardID }]));