react。用于 onCopy 事件的 preventDefault() 不起作用

IT技术 javascript reactjs
2021-05-09 22:26:30

我试图弄清楚如何让剪贴板事件false在 onCopy 事件上返回我用于测试onCopy处理程序和e.preventDefault()方法。但是文本被毫无障碍地复制到缓冲区!我想念什么?

先感谢您。

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import ReactDOMServer from 'react-dom/server';
import './index.css';


class Copy extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      time: '',
      timer: false,
      counter: 0
    };

    this.handlerCopy = this.handlerCopy.bind(this);
  }

  handlerCopy(e) {

    e.preventDefault(); // must prevent the current event

    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));

    alert('Don\'t copy it!');
  }

  render() {
    return (
      <React.Fragment>
        <p onCopy={this.handlerCopy}>Copy me!</p>
        <p>Copy count: {this.state.counter}</p>
      </React.Fragment>
    );
  }
}

ReactDOM.render(
<Copy />,
document.getElementById('root'));
3个回答

这真是个好问题!

之所以会发生这种情况,是因为 React 的实际事件侦听器也在文档的根部,这意味着 click 事件已经冒泡到了根部。您可以使用e.nativeEvent.stopImmediatePropagation()来阻止其他事件侦听器。

试试看:

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import ReactDOMServer from 'react-dom/server';
import './index.css';


class Copy extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      time: '',
      timer: false,
      counter: 0
    };

    this.handlerCopy = this.handlerCopy.bind(this);
  }

  handlerCopy(e) {
    console.log(e.target.innerHTML);
    e.preventDefault();
    e.nativeEvent.stopImmediatePropagation();

    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));

    alert('Don\'t copy it!');
  }

  render() {
    return (
      <React.Fragment>
        <p onCopy={this.handlerCopy}>Copy me!</p>
        <p>Copy count: {this.state.counter}</p>
      </React.Fragment>
    );
  }
}

ReactDOM.render(
<Copy />,
document.getElementById('root'));

这应该是评论,但我没有足够的声誉。我认为 e.preventDefault() 对(至少)React 16 来说已经足够了。

Codesandbox 上的工作示例

上面提到的解决方案似乎对我不起作用,但是如果谈论状态中的计数器值,它可以通过以以下方式编写 handlerCopy 来正确管理(状态值的更新)。

import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import ReactDOMServer from 'react-dom/server';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      time: '',
      timer: false,
      counter: 0
    };
  }

   handlerCopy(e) {
    var val = this.state.counter;
    val = val + 1;
    this.setState({
      counter: val
    }, function(){
      console.log('new acounter:- ', this.state.counter);
    })
    alert('Don\'t copy it!');
  }


  render() {
    return (
      <React.Fragment>
        <p onCopy={(e) => this.handlerCopy(e)}>Copy me!</p>
        <p>Copy count: {this.state.counter}</p>
      </React.Fragment>
    );
  }
}
document.addEventListener('click', function(e) {
    console.log('propagation',e)
  }, false);


export default App;

上面提到的这个 handlerCopy 函数没有对我做任何改变@Max Wolfen

 handlerCopy(e) {
    console.log(e.target.innerHTML);
    e.preventDefault();
    e.nativeEvent.stopImmediatePropagation();

    this.setState(prevState => ({
      counter: prevState.counter + 1
    }));

    alert('Don\'t copy it!');
  }