【问题标题】:How to stop JavaScript events when React component unmounts?React 组件卸载时如何停止 JavaScript 事件?
【发布时间】:2018-09-25 23:57:42
【问题描述】:

背景:
我有一个用 React 构建的网络应用程序(目前是 16.4.2)。它只会在触摸屏上使用。它由大量的按钮组成,因为它都是触摸的,所以我使用 touchstart/touchend 来处理这些操作。

示例: 这是我如何使用事件的基本示例。您单击一个按钮,它将this.state.exampleRedirect 设置为true,这反过来又使组件重新渲染,然后转到新页面(使用react-router-dom)。这一切都很好。

<button
  type='button'
  onTouchStart={() => this.setState({ exampleRedirect: true })}
  className='o-button'>
  Open modal
</button>

问题:
我最初使用 onClick 来处理按钮,但遇到了问题,因为我的用户手指肥厚,技术背景不多,当他们触摸按钮时,他们会将手指拖到按钮上,但不会触发点击. OnTouchStart 通过在发生任何触摸(拖动、滑动、点击等)时触发来解决此问题。

问题在于 onTouchStart。用户触摸按钮,它会快速更改页面(使用路由器)并重新呈现新页面。该应用程序很快,所以这几乎是瞬时的,这意味着当新页面加载时,用户的手指通常仍在屏幕上,因此在他们触摸的任何地方都会触发另一个触摸事件。这通常是另一个路由按钮,因此它只会在屏幕上触发,直到他们抬起手指为止。

我正在通过延迟在每个页面加载时启用按钮来解决此问题。

// example component
import React, { Component } from 'react';

class ExampleComponent extends Component {
  state = { buttonsDisabled: true }

  // after 300ms, the buttons are set to enabled (prevents touch events 
  // from firing when the page first loads
  componentWillMount() {
    timeoutId = setTimeout(() => {
      this.setState({ buttonsDisabled: false });
    }, 300);
  }

  render() {
    return (
      // button in render method
      <button
        disabled={this.state.buttonsDisabled}
        type='button'
        onTouchStart={() => this.setState({ exampleRedirect: true })}
        className='o-button'>
        Open modal
      </button>
    );
  }

有没有更好的方法?或者一种做我正在做的事情的方法,但在全球范围内,所以我不必在大约 100 个组件中添加这个 jankity 代码?

谢谢!

【问题讨论】:

    标签: javascript reactjs touch touchstart


    【解决方案1】:

    您应该使用onTouchEnd,而不是使用onTouchStart 事件(当触摸点放置在触摸表面上时触发并使用超时),因为它会被触发当触摸点从触摸表面移开时,从而确保上述情况不会发生。

    // example component
    import React, { Component } from 'react';
    
    class ExampleComponent extends Component {
      state = { buttonsDisabled: true }
    
      // after 300ms, the buttons are set to enabled (prevents touch events 
      // from firing when the page first loads
      componentWillMount() {
        timeoutId = setTimeout(() => {
          this.setState({ buttonsDisabled: false });
        }, 300);
      }
    
      render() {
        return (
          // button in render method
          <button
            disabled={this.state.buttonsDisabled}
            type='button'
            onTouchEnd={() => this.setState({ exampleRedirect: true })}
            className='o-button'>
            Open modal
          </button>
        );
      }
    

    【讨论】:

    • 当然。这很好用。踢自己...谢谢!
    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 2017-03-03
    • 1970-01-01
    • 2021-04-26
    • 2019-03-19
    • 1970-01-01
    相关资源
    最近更新 更多