我正在尝试重新渲染组件,以在用户阻止或允许其位置已知时(通过单击Chrome浏览器地址左侧的信息图标)来隐藏或显示“使用当前位置”按钮。我对为什么下面第一个示例起作用(即,在更改权限后立即正确切换按钮)为何感到困惑,但第二个却没有(需要刷新)。

我试图通过简单地定义常量permission.state !== 'denied'删除重复的hasPermission

另外,我不清理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)时,您将创建一个事件侦听器,该事件侦听器将始终使用相同的值调用setHasPermission:上面保存的permission.state !== 'denied'的结果。

在第一个示例中,它起作用是因为在事件回调中对permission.state !== 'denied'进行了评估。

很清楚吗?

为了进行清理,useEffect可以返回一个函数,该函数将在卸载组件时被调用。请检查https://reactjs.org/docs/hooks-effect.html#example-using-hooks-1

关于javascript - 回调不更新状态的useEffect,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55966230/

10-11 21:43