Add a new object to array via useRecoilState

Good day 🙂

I faced with a problem with useRecoilState.
I have an external file with an array of objects:

export const objectPositionState = atom({
    key: "objectPosition", // unique ID (with respect to other atoms/selectors)
    default: [
        // {id:1, x: -2.4, y: 0, z: 1},
        // {id:2, x: 2.4, y: 0, z: 2 },
        // {id:3, x: 0, y: 0, z: 3 },
    ],
})

If i uncomment these 3 lines it will show 3 objects with no problem, BUT when i adding new objects to this array on timer, it will add only one object (not keep adding on each tick of timer, as i expected)…

Here is how i trying to add objects to this array on timer:

    const [objects, setObjects] = useRecoilState(objectPositionState);
//timer
    const MINUTE_MS = 3000;

 // I have specific positions for X
    const positionValues = [-2.4, 0, 2.4];
    let objectPosition = {x:0, y:0, z:5};

    function getRandomIntInclusive(min, max) {
        min = Math.ceil(min);
        max = Math.floor(max);
        return Math.floor(Math.random() * (max - min + 1)) + min;
      };

//here is the timer with a new object adding function
useEffect(() => {
    const interval = setInterval(() => {
        objectPosition.x = positionValues[getRandomIntInclusive(0,2)];

        setObjects([...objects,
        {
            id:uuidv4(),
            x:objectPosition.x,
            y:objectPosition.y,
            z:objectPosition.z,
        }])
    
    }, MINUTE_MS);


    return () => clearInterval(interval); 
  }, [])

I guess i missing something, but can’t find out what exactly…
Kindly asking for your support 🙂

>Solution :

I search in documentation and found that its works like useState in React. So try to use it with callback function, it should look like this

setObjects(previous => [...previous,
        {
            id:uuidv4(),
            x:objectPosition.x,
            y:objectPosition.y,
            z:objectPosition.z,
        }])

Read about batching in React

Leave a Reply