Данные об ориентации устройства и выборке внешних данных API json кажутся конфликтующими. Как я могу это исправить? - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь получить данные об ориентации устройства и получить данные API с помощью ловушек реагирования, но это похоже на конфликт.

Если бы я мог получить данные об ориентации устройства, то я не смог бы получить данные API (я думаю, что когда я мог получить данные об ориентации устройства, сервер не работал) и когда сервер работалЯ не смог получить данные об ориентации устройства.Поскольку сервер отправляет данные по HTTP, а не по https, я попробовал их на локальном сервере, но все равно не получилось.Кажется, что есть проблема в использовании реакционных хуков и useEffect, но не уверен.

const [alpha, setAlpha] = React.useState(0.0)

React.useEffect(() => {
    const handleOrientation = e => setAlpha(e.alpha)
    window.addEventListener("deviceorientation", handleOrientation, true)

    return () => {
        window.removeEventListener("deviceorientation", handleOrientation)
        }
}, [])

const [centerX, setCenterX] = React.useState(0.0)
const [centerY, setCenterY] = React.useState(0.0)
const [deviceX1, setDeviceX1] = React.useState(0.0)
const [deviceY1, setDeviceY1] = React.useState(0.0)
const [deviceX2, setDeviceX2] = React.useState(0.0)
const [deviceY2, setDeviceY2] = React.useState(0.0)

const [timer, setTimer] = React.useState(null)
const [isMounted, setIsMounted] = React.useState(false)

async function updateDevicePosition() {
    try {
        const result = await fetch("http://192.168.10.233:34599/")
        const data = await result.json()
        setCenterX(data[0].x)
        setCenterY(data[0].y)
        setDeviceX1(data[1].x)
        setDeviceY1(data[1].y)
        setDeviceX2(data[2].x)
        setDeviceY2(data[2].y)
    } catch (e) {
        console.error(e)
    }
    clearTimeout(timer)
    setTimer(setTimeout(updateDevicePosition, 200))
}

React.useEffect(() => {
    if (!isMounted) {
        updateDevicePosition()
        setIsMounted(true)
    }
})

После получения всех данных надеюсь рассчитать положение и ориентацию устройства.

1 Ответ

0 голосов
/ 25 июня 2019

Я думаю, что вы действительно близки, но я бы сделал это немного по-другому.Во-первых, у меня была бы вся позиция в одном состоянии:

const [devicePosition, setDevicePosition] = React.useState({
  centerX: 0.0,
  centerY: 0.0,
  deviceX1: 0.0,
  deviceY1: 0.0,
  deviceX2: 0.0,
  deviceY2: 0.0,
})

Во-вторых, я бы удалил компонент isMounting из состояния.Вы не хотите использовать состояние, чтобы определить, следует ли обновлять состояние.Вы можете обновить isMounting на не смонтированном компоненте.

В-третьих, я бы удалил useEffect, которое вызывается при каждом рендеринге.Маловероятно, что вам нужно делать вызовы остальных при каждом рендере.Основываясь на коде, я думаю, что вы хотите сделать вызов при первом рендере, а затем установить таймер.

Ниже показаны эти изменения.

const [alpha, setAlpha] = React.useState(0.0)
const [devicePosition, setDevicePosition] = React.useState({
  centerX: 0.0,
  centerY: 0.0,
  deviceX1: 0.0,
  deviceY1: 0.0,
  deviceX2: 0.0,
  deviceY2: 0.0,
})
const [timer, setTimer] = React.useState(null)

let isMounted = true
React.useEffect(() => {
    const handleOrientation = e => setAlpha(e.alpha)
    window.addEventListener("deviceorientation", handleOrientation, true)
    updateDevicePosition() //make rest call on mounting

    return () => {
        window.removeEventListener("deviceorientation", handleOrientation)
        isMounted = false
    }
}, [])

async function updateDevicePosition() {
    try {
        const result = await fetch("http://192.168.10.233:34599/")
        const data = await result.json()
        if (isMounted) { //so you aren't setting state on an unmounted component
          setDevicePosition({
            centerX: data[0].x,
            centerY: data[0].y,
            deviceX1: data[1].x,
            deviceY1: data[1].y,
            deviceX2: data[2].x,
            deviceY2: data[2].y,
          })
       }
    } catch (e) {
        console.error(e)
    }
    if (isMounted) {
      clearTimeout(timer)
      setTimer(setTimeout(updateDevicePosition, 200))
    }
}


...