简体   繁体   中英

useEffect with callback not updating state

I'm trying to re-render a component to hide or show a 'Use current location' button when the user blocks or allows their location to be known (by clicking on the info icon to the left of the browser address in Chrome). I'm totally confused by why the first example below works, (ie. the button toggled appropriately as soon as the permission is changed) but the second doesn't (it requires a refresh).

I was attemping to remove the duplicate permission.state !== 'denied' by simply defining the constant hasPermission .

Also, I don't clean up the onchange listener. How do I do this? Can I just assign to null or delete the property?

Works:

    useEffect(() => {
        navigator.permissions.query({ name: 'geolocation' }).then(permission => {
            setHasPermission(permission.state !== 'denied')
            permission.onchange = () =>
                setHasPermission(permission.state !== 'denied')
        })
    }, [])

Doesn't work:

useEffect(() => {
    navigator.permissions.query({ name: 'geolocation' }).then(permission => {
        const hasPermission = permission.state !== 'denied';
        setHasPermission(hasPermission)
        permission.onchange = () => 
            setHasPermission(hasPermission)
    })
}, [])

Basically, permission.onchange is defined only once.

So, when you define, in your second example, permission.onchange = () => setHasPermission(hasPermission) you create an event listener that will always call setHasPermission with the same value: the result of permission.state !== 'denied' saved above.

In your first example, it works because permission.state !== 'denied' is evaluated in the event callback.

Is it clear enough ?

For cleanup, useEffect can return a function that will be called when component unmounts. Please check https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM