带回调的 useEffect 不更新状态

useEffect with callback not updating state

我正在尝试重新呈现组件以在用户阻止或允许知道其位置时隐藏或显示 'Use current location' 按钮(通过单击浏览器左侧的信息图标Chrome 中的地址)。我完全不明白为什么下面的第一个示例有效(即,一旦更改权限,按钮就会适当切换),但第二个示例无效(它需要刷新)。

我试图通过简单地定义常量 hasPermission.

来删除重复项 permission.state !== 'denied'

此外,我没有清理 onchange 侦听器。我该怎么做呢?我可以只分配给 null 或删除 属性 吗?

作品:

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

无效:

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

基本上,permission.onchange只定义了一次。

因此,当您在第二个示例中定义 permission.onchange = () => setHasPermission(hasPermission) 时,您会创建一个事件侦听器,它将 始终 使用相同的值调用 setHasPermissionpermission.state !== 'denied' 的结果保存在上面。

在您的第一个示例中,它之所以有效,是因为 permission.state !== 'denied' 在事件回调中进行了评估。

够清楚了吧?

为了清理,useEffect 可以 return 组件卸载时调用的函数。请检查 https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1