SetState() блокирует пользовательский интерфейс при запуске двух setState()

Вот мой componentDidMount() метод:

componentDidMount() {
    const subscription = accelerometer.subscribe(({ x, y, z, timestamp }) => {
        x = Math.trunc(x*100);
        this.setState({x})
    });
}

В приведенном выше методе состояние меняется каждые 100 миллисекунд. Я использовал это состояние в своем методе render(), как показано ниже:

render() {
    const animatedImageStyle = StyleSheet.flatten([
      styles.captureButton,
      {
        transform: [{rotateZ:this.state.x + 'deg'}]
      }
    ])

    return (
      <SideMenu 
        menu = {leftMenu}
        isOpen = {this.state.isOpenLeftMenu}
        menuPosition = {'left'}
        bounceBackOnOverdraw = {false}
        onChange = {(isOpenLeftMenu) => this.updateLeftMenuState(isOpenLeftMenu)}
      >
        <View>
            <TouchableOpacity 
                activeOpacity = {0.5}
                onPress = {(this.state.recordingMode == 'camera')?() => this.takePicture():() => this.toggleRecording()}
              > 
                <Image 
                  source = {require('../assets/imgs/forRotate.png')}
                  style = {animatedImageStyle}
                />
            </TouchableOpacity>
        </View>
      </SideMenu>
    )
}

Теперь проблема в том, что когда я пытаюсь открыть боковое меню, оно не открывается, я имею в виду, что оно открывается, но слишком сильно висит. Все мое приложение слишком сильно висит.

Я думаю, что это из-за метода ниже:

updateLeftMenuState(isMenuOpen) {
    this.setState({
      isOpenLeftMenu:isMenuOpen
    })
}

Обратите внимание, что я обновляю другое состояние под названием isOpenLeftMenu, которое может быть заблокировано во время обновления состояния x.

Может ли кто-нибудь сказать мне, что здесь не так?

Каждый раз, когда вы устанавливаете состояние, представления должны перерисовываться. Это означает, что вы уничтожаете и перерисовываете свой интерфейс 10 раз в секунду, что довольно сложно с вычислительной точки зрения. Попробуйте уменьшить частоту смены состояния.

Elan Hamburger 29.05.2019 05:50

Я не могу замедлить частоту изменения состояния, потому что требуется 100 миллисекунд. Кстати, замедление до 1 секунды все еще не сработало.

Kishan Bharda 29.05.2019 05:52

можете ли вы проверить, чтобы пропустить setState, пока вы не получите другие значения? например, нам не нужно устанавливать состояние, если нам нужно снова установить то же значение, что и уже установлено.

Ashish 29.05.2019 06:50

Это хорошая идея @Ashish, но в моем приложении есть функциональность, в которой я поворачиваю кнопку в соответствии с поворотом устройства (не только от портрета к ландшафту, но и от поворота), поэтому мне нужно значение каждой миллисекунды.

Kishan Bharda 29.05.2019 06:54

@KishanBharda попробуйте с переменной компонента. Состояние настройки будет каждый раз перемонтировать компонент. и если вы определите его в переменной компонента, например this.x = x. если это может помочь.

Ashish 29.05.2019 06:58

@Ashish Если я использую this.x в своем компоненте, изменения не влияют на компонент. Поэтому я не получу желаемого результата.

Kishan Bharda 29.05.2019 07:13

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

Mohammed Ashfaq 29.05.2019 08:34

@MohammedAshfaq Пожалуйста, не могли бы вы сказать мне, как я могу это решить?

Kishan Bharda 29.05.2019 08:41
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
8
868
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

вы можете переместить представление анимации в отдельный компонент вместе с логикой подписки. Таким образом, обновление состояния этого компонента не повлияет на компонент SideMenu.

Спасибо за ваш ответ, но это помогло мне только в идеальном состоянии настроек, но не решило мою основную проблему.

Kishan Bharda 29.05.2019 11:43

вы можете переместить представление анимации в отдельный компонент вместе с логикой подписки и Try.

Mohammed Ashfaq 31.05.2019 08:49

да. Абсолютно прав @MohammedAshafaq. У меня сработало перемещение анимации в отдельном компоненте. Спасибо. Пожалуйста, отредактируйте ответ с комментарием выше, чтобы я мог принять его и помочь кому-то.

Kishan Bharda 31.05.2019 09:01

Другие вопросы по теме