Search code examples
androidreact-nativereact-hooksuse-effectflatlist

Right way to use useEffect in react native


Here is my sample React component:

const OwnerView = () => {
    const [monthlyCharge, setMonthlyCharge] = useState(0)
    useEffect(() => {
        getPerMonthCharges(ownerPhoneNumber, vehicles.length)
    }, [])

    async function getPerMonthCharges(ownerPhoneNumber, noOfCars) {
        console.log(`inside getPerMonthCharges`);
        try {
            const serviceProviderChargesDoc = await firestore().collection(`${serviceProviderId}_charges`).doc(`${ownerPhoneNumber}`).get()
            if (serviceProviderChargesDoc?.data()?.chargesPerMonth > 0) {
                setMonthlyCharge(serviceProviderChargesDoc?.data()?.chargesPerMonth)
                return
            }
        } catch (error) {
            console.log(`Error while fetching monthly charge ${error}`);
        }
        setMonthlyCharge(noOfCars * perMonthGeneralCharge)
        console.log(`done with getPerMonthCharges`);
    }
}

There is a possibility that OwnerView gets unmounted even before getPerMonthCharges() completes its execution. Therefore in case OwnerView gets unmounted I receive a warning that am doing state update on an unmounted component and this is a non-op. Can someone please highlight what is your observation and right way to write this piece of code?


Solution

  • There are many ways to address this

    1. You can check if the component is still Mounted, a bit ugly approach I agree, but quite a standard one (I would just use something like useAsync from react-use, which essentially does the same, but hides the ugliness)
    2. Move loading logic outside of UI and make part of the global state (Redux, MobX, Apollo, or any other state management library), it would be in lines of separation of concerns and should make your code more readable.
    3. The worst would be to prevent your user from any actions, while content is loading - making your app seem clunky, but React would not complain anymore.

    The closest to the right way would be 2, but this can sparkle religious debates and some witch-burning, which I'm not a fan of.