useEffect с обратным вызовом не обновляет состояние - PullRequest
1 голос
/ 03 мая 2019

Я пытаюсь повторно выполнить рендеринг компонента, чтобы скрыть или показать кнопку «Использовать текущее местоположение», когда пользователь блокирует или позволяет узнать свое местоположение (нажав на значок информации слева от адреса браузера в Хром). Я полностью сбит с толку тем, почему первый пример, приведенный ниже, работает (т. Е. Кнопка переключается соответствующим образом при изменении разрешения), а второй - нет (требуется обновление).

Я пытался удалить дубликат 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)
    })
}, [])

1 Ответ

1 голос
/ 03 мая 2019

Как правило, 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

...