Изменения состояния реакции не всегда работают в мобильном Интернете

#reactjs #react-native #state #react-native-web #expo-web

#reactjs #react-native #состояние #react-native-web #expo-web

Вопрос:

Мой пример работает следующим образом:

У меня есть кнопка, которая показывает изображение (через изменение состояния путем отправки из useReducer) в течение 400 мс при нажатии. Через 400 мс изображение снова скрывается, а кнопка становится видимой. В настольном браузере это работает довольно хорошо. Но на мобильном устройстве есть проблемы с производительностью. Изображение не всегда отображается при нажатии. Смотрите следующие GIF-анимации ниже для понимания:

Это мой исходный код:

   const initialState = {
    shouldObserve: false,
  };
  
  function reducer(state, action) {
    switch (action.type) {
      case "observe":
        return { shouldObserve: true };
      case "reset":
        return initialState;
      default:
        throw new Error();
    }
  }

  const [state, dispatch] = useReducer(reducer, initialState);
  
  useEffect(() => {
    // Prevent calling useEffect at first Render
    if (firstUpdate.current) {
      firstUpdate.current = false;
      return;
    }

    const { shouldObserve } = state;
    if (shouldObserve) {
      setTimeout(() => {
        dispatch({ type: "reset" });
      }, TIME_TO_OBSERVE);
    }
  }, [state]);
 

GIF-анимация:

На рабочем столе (работает хорошо):Для рабочего стола

На мобильном устройстве (не всегда отображается изображение): Мобильный

Есть ли какой-либо способ, чтобы я мог гарантировать, что изображение отображается на 100% (всегда)?

Дополнительная информация о моем стеке: я использую Expo для разработки приложения для iOS, Android и Web. Вывод веб-версии — это React Native Web, поэтому здесь используется внутренний React.

Ответ №1:

Может быть, попробуйте что-то вроде этого:

 import React, { useEffect, useState } from "react";
import "./styles.css";

export default function App() {
  const [show, setShow] = useState(false);

  useEffect(() => {
    const timer = setTimeout(() => {
      setShow(false);
    }, 200);
    return () => clearInterval(timer);
  }, [show]);

  return (
    <div className="App">
      <div onClick={() => setShow(true)}>
        {show ? <div>image</div> : <div>start</div>}
      </div>
    </div>
  );
}
 

вот изолированная среда для тестирования кода: https://codesandbox.io/s/nervous-khorana-l903t?file=/src/App.js:0-461

Комментарии:

1. К сожалению, я не увидел никаких улучшений. Ваш исходный код включает 2 раздела здесь. Можете ли вы попробовать переключить изображение и div? Если я переключаю текст и кнопку, он работает так, как ожидалось, но не с компонентом изображения

2. будет делать одну секунду.

3. @realarb Я вставил изображение вместо div, и, похоже, оно работает просто отлично.

4. могу я спросить, как вы загружаете свое изображение? В настоящее время я тестирую его на симуляторе ios, и он работает так, как ожидалось.

5. Я использую Expo и предварительно загружаю свое изображение с помощью useAssets из expo-asset. Это обычный компонент React Native Image <Image style={styles.image} source={require(«./assets/react.png»)} />