React - 如何在合成事件被回收之前触发preventDefault()?

问题描述 投票:4回答:3

我在React组件中有以下函数,该组件在单击链接时运行:

onClick(e, { name }) {
    e.stopPropagation();

    const doIt = await checkSomething();

    if (doIt) {
        e.preventDefault();
        doSomethingElse();
    }
}

问题是,到达e.preventDefault()时,合成事件被回收。那么,如果点击它,当需要一些逻辑来计算这个决定时以及合成事件被回收之前,我如何告诉浏览器不要关注链接?

reactjs preventdefault
3个回答
2
投票

处理此问题的一种方法是使用preventDefault,当操作完成并且您需要路由时,使用history.push()自行调用路由逻辑

onClick(e, { name }) {
    e.stopPropagation();
    e.preventDefault();
    const doIt = await checkSomething();

    if (doIt) {
        doSomethingElse();
    } else {
        this.props.history.push('/pathToRoute');
    }
}

how to Programmatically navigate with React-router上查看此答案


2
投票

我只想在这里提出一个想法。

如果您不能或不想以编程方式进行URL重定向,那么还有另一种选择。 您可以嵌套一个函数(currying)并仅在完成逻辑后调用第二个函数。 请注意,这将要求您将嵌套函数编写为IIFE。


Here is a small proof of concept using JavaScript (open console):

const el = document.getElementById("link");


function onLinkClick() {
  console.log('doing some stuff..');
  for(let i = 0; i < 500; i++){
  	console.log(`doing more stuff #${i}`);  
  }
  return function(e) {
    // this will trigger with the actuall event (note this is an IIFE)
    console.clear();
  }();
}

el.addEventListener('click', onLinkClick);
#big {
  min-height: 950px;
}
<div id="big">
  <a id="link" href="#test">Click to get to the bottom of the page</a>
</div>

<div id="test">Bottom of page</div>

反应的例子:

class App extends React.Component {

  onClick = (e) => {
    console.log('doing some stuff..');
    for (let i = 0; i < 500; i++) {
      console.log(`doing more stuff #${i}`);
    }
    return ((e) => {
      //console.log(e, "inner function")
      console.clear();
    })(e)
  }

  render() {
    return (
      <div>
        <div style={{ height: '950px' }}>
          <a href="#test" onClick={this.onClick} >Click to get to the bottom of the page</a>
        </div>

        <div id="test">Bottom of page</div>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

1
投票

要在事件上使用preventDefault,您需要在回调函数返回之前执行此操作。在完成异步任务后,您无法执行此操作。

如果你看看MDN Event.preventDefault Notes,你会发现它说你必须在事件流程中的某个地方调用它。

在事件流的任何阶段调用preventDefault()会取消事件,这意味着不会发生由于事件而通常由实现采取的任何默认操作。

你也可以参考这个问题:event.preventDefault in async functions 。在最佳答案中,您将看到提及使用await以及event.preventDefault()如何在第一个await声明之前发生。这适用于使用promises或任何异步操作。

作为旁白:

如果要以异步方式访问事件属性,则应在事件上调用event.persist(),这将从池中删除合成事件,并允许用户代码保留对事件的引用。

这是SyntheticEvent documentation

© www.soinside.com 2019 - 2024. All rights reserved.