React Native useCallback state not updating

545 Views Asked by At

I am currently trying to implement useCallback for a function which updates an existing state array by adding a new object.

const [objects, setObjects] = useState([]);



useEffect(() => {
    dropApiService.GetObjects(drop.id).then(result => {
        if (result && result.data && result.data.success) {
            setObjects(result.data.items.sort((a, b) => moment(a.createdDate) < moment(b.createdDate)));
            setLoading(false);
        }
    });
}, []);


const handleFileAdd = useCallback((result) => {
        if (result && result.length > 0) {

            const newFile = {
                ...result[0],
                createdDate: moment()
            }

            const currentObjects = [...objects];
            currentObjects.push(newFile);




            console.log(JSON.stringify(currentObjects));

            //Got files
            setObjects(currentObjects);
        }
}, [objects]);

'handleFileAdd' is called when the user selects a file using document picker. This code 'works' however the 'objects' state object doesn't have the latest state value.

What am I doing wrong here?

Cheers

1

There are 1 best solutions below

2
On

useCallback The useCallback hook has a primary and specific function: avoid unnecessary re-renders in your code, making your application faster and more efficient.

The useCallback hook receives a function as a parameter, and also an array of dependencies. The useCallback hook will return a memoized version of the callback, and it’ll only be changed if one of the dependencies has changed.

Ref : https://www.telerik.com/blogs/usecallback-useref-two-react-hooks-you-should-learn

We can wrap the addNote function with the useCallback hook, and pass as a dependency the setNotes updater function, because the only thing that’s a dependency of our Button component is the setNotes.

const addNote = useCallback(() => {
 const newNote = "random";
 setNotes(n => [...n, newNote]);
}, [setNotes]);

In your case, pls use

        setObjects(o => [...o, newFile]);