'Component not updating after useEffect call

I am trying to delete an Item from my database using a Modal and then show the list of item remaining.

Everything works, my item is deleted correctly, but my component update only when I navigate to it, it's not updating after my modal is closed.

I want my component to refresh after my modal is closed.

Here is my code:
My modal:

<Modal visible={modalOpen} transparent={true} animationType='fade'>
  <View>
    <TouchableOpacity onPress={() => deleteMachineFunction()}>
         <Text style={styles.delete}>Delete</Text>
    </TouchableOpacity>
  </View>
</Modal>

my deleteMachineFunction() which is called after pressing 'Delete'

    const deleteMachineFunction = () => {
        dispatch(deletemachine(machineId))

        firebase.firestore()
        .collection('users')
        .doc('WDaEyHg9wMhqFjqA1zzeYaD6sts1')
        .update({
            userMachineList: firebase.firestore.FieldValue.arrayRemove(machineId)
        })
        //close modalle modal
        setModalOpen(false)
    }

So above, my modal useState (modalOpen, setModalOpen) is updating true to false.

Here is my useEffect hook:

   useEffect(() => {
        const unsubscribe = navigation.addListener('focus', () => {
            firebase.firestore()
            .collection("users")
            // .doc(firebase.auth().currentUser.uid)
            .doc('WDaEyHg9wMhqFjqA1zzeYaD6sts1')
            .get()
            .then((snapshot) => {
                if(snapshot.exists){
                   setCloudUserMachineList(snapshot.data().userMachineList)
                } else {
                    console.log('not working')
                }
            })
        });
    
        // Return the function to unsubscribe from the event so it gets removed on unmount
        return unsubscribe;

      }, [navigation, modalOpen]);

I was thinking by putting modalOpen in the useEffect array, my Component will update automatically after modalOpen turn to false but it's not working.

Can someone tell me what I am doing wrong?



Solution 1:[1]

Since you call get(), you're only getting the data once. If the data is updated after that, your setCloudUserMachineList won't be updated.

If you want to listen for updates to the data, use onSnapshot instead of get():

useEffect(() => {
    firebase.firestore()
    .collection("users")
    .doc('WDaEyHg9wMhqFjqA1zzeYaD6sts1')
    .onSnapshot((snapshot) => { // ?
        if(snapshot.exists){
           setCloudUserMachineList(snapshot.data().userMachineList)
        } else {
            console.log('not working')
        }
    })
}, [modalOpen])

Solution 2:[2]

if you want to update data only on modal close and open, then your useEffect() function can be written like this:

useEffect(() => {
    firebase.firestore()
    .collection("users")
    // .doc(firebase.auth().currentUser.uid)
    .doc('WDaEyHg9wMhqFjqA1zzeYaD6sts1')
    .get()
    .then((snapshot) => {
        if(snapshot.exists){
           setCloudUserMachineList(snapshot.data().userMachineList)
        } else {
            console.log('not working')
        }
    })
}, [modalOpen])

it will get fresh data from firebase every time the modal is opened or closed and I don't understand why you added this functionality as a focus listener to navigation.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Frank van Puffelen
Solution 2 Mohammad Salehi