我在React组件中有以下函数,该组件在单击链接时运行:
onClick(e, { name }) {
e.stopPropagation();
const doIt = await checkSomething();
if (doIt) {
e.preventDefault();
doSomethingElse();
}
}
问题是,到达e.preventDefault()
时,合成事件被回收。那么,如果点击它,当需要一些逻辑来计算这个决定时以及合成事件被回收之前,我如何告诉浏览器不要关注链接?
处理此问题的一种方法是使用preventDefault
,当操作完成并且您需要路由时,使用history.push()
自行调用路由逻辑
onClick(e, { name }) {
e.stopPropagation();
e.preventDefault();
const doIt = await checkSomething();
if (doIt) {
doSomethingElse();
} else {
this.props.history.push('/pathToRoute');
}
}
我只想在这里提出一个想法。
如果您不能或不想以编程方式进行URL重定向,那么还有另一种选择。 您可以嵌套一个函数(currying)并仅在完成逻辑后调用第二个函数。 请注意,这将要求您将嵌套函数编写为IIFE。
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>
要在事件上使用preventDefault
,您需要在回调函数返回之前执行此操作。在完成异步任务后,您无法执行此操作。
如果你看看MDN Event.preventDefault Notes,你会发现它说你必须在事件流程中的某个地方调用它。
在事件流的任何阶段调用preventDefault()会取消事件,这意味着不会发生由于事件而通常由实现采取的任何默认操作。
你也可以参考这个问题:event.preventDefault in async functions
。在最佳答案中,您将看到提及使用await
以及event.preventDefault()
如何在第一个await
声明之前发生。这适用于使用promises或任何异步操作。
作为旁白:
如果要以异步方式访问事件属性,则应在事件上调用event.persist(),这将从池中删除合成事件,并允许用户代码保留对事件的引用。