反应onClick和preventDefault()链接刷新/重定向?


84

我正在渲染一个带有react的链接:

render: ->
  `<a className="upvotes" onClick={this.upvote}>upvote</a>`

然后,上面有upvote函数:

upvote: ->
  // do stuff (ajax)

在链接建立之前,我已经跨过那个地方,但是我需要切换到链接,这就是麻烦了-每次我.upvotes刷新页面时,到目前为止,我已经尝试过以下操作:

event.preventDefault()-不起作用。

upvote: (e) ->
  e.preventDefault()
  // do stuff (ajax)

event.stopPropagation()-不起作用。

upvote: (e) ->
  e.stopPropagation()
  // do stuff (ajax)

返回false-不起作用。

upvote: (e) ->
  // do stuff (ajax)
  return false

我也已经在index.html中使用jQuery尝试了上述所有方法,但似乎没有任何效果。我在这里应该做什么,我做错了什么?我已经检查了event.type,click因此我想应该可以避免以某种方式重定向?

对不起,我是React的新秀。

谢谢!


1
您是否正在尝试将es2015语法用于这些功能?
erichardson16年

您要创建什么样的组件?无国籍?createClass?
markthethomas

您可以确认onClick确实有效upvote吗?这可能是一个上下文问题。
thangngoc89 '03 /

1
使用preventDefault
onmyway133

1
e.PreventDefault()独自为我工作(反应16.0.0-beta5)
felix-b

Answers:


67

React事件实际上是合成事件,而不是本机事件。就像这里写的:

事件委托:React实际上并未将事件处理程序附加到节点本身。当React启动时,它开始使用单个事件侦听器在顶层侦听所有事件。在安装或卸载组件时,只需简单地从内部映射中添加或删除事件处理程序即可。当事件发生时,React知道如何使用此映射来调度它。当映射中没有事件处理程序时,React的事件处理程序就是简单的无操作。

尝试使用Use Event.stopImmediatePropagation

upvote: (e) ->
  e.stopPropagation();
  e.nativeEvent.stopImmediatePropagation();

74

该解决方案的完整版本将方法封装在onClick中,传递e并使用本机e.preventDefault();。

upvotes = (e, arg1, arg2, arg3 ) => {
    e.preventDefault();
    //do something...
}

render(){
    return (<a type="simpleQuery" onClick={ e => this.upvotes(e, arg1, arg2, arg3) }>
      upvote
    </a>);
{

e.preventDefault();之间有区别吗?在功能的开始还是结束?放在哪里更有意义?
Sartheris Stormhammer,

我认为最好在开始时使用它
罗马

这是错误的做法,请阅读有关箭头功能以及.bind(this)React应用程序中bin上下文的信息。例如:medium.freecodecamp.org/…–
快乐,

除了这只是创建一个传递参数的函数。如果您已经在使用react和ES6,则不需要作用域函数。通过将其与构造函数绑定在一起,您可以轻松完成此操作。
伊恩内

请注意,如果在调用e.preventDefault()之前触发了渲染(例如,通过更改状态),则将无效。因此最好将其作为事件处理程序的第一条语句。
Thim Anneessens

16

尝试bind(this),这样您的代码如下所示-

 <a className="upvotes" onClick={this.upvote.bind(this)}>upvote</a>

或者如果您正在构造器中编写es6 react组件,则可以执行此操作

constructor(props){
   super(props);
   this.upvote = this.upvote.bind(this);
}

upvote(e){   // function upvote
   e.preventDefault();
   return false

}

9
这没有区别。您之所以感到不满,是因为人们this在其事件处理程序中拥有一个完全不同的问题。
迪米塔尔·内斯托罗夫'18

8

渲染:-> <a className="upvotes" onClick={(e) => {this.upvote(e); }}>upvote</a>


1
这是错误的做法,请阅读有关箭头功能以及.bind(this)React应用程序中bin上下文的信息。例如:medium.freecodecamp.org/…–
快乐,

createReactClass或Autobinding或使用npm包“ auto-bind”
xjinjin

6

在这样的背景下

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

如您所见,您必须显式调用preventDefault()。我认为文档可能会有所帮助。


2

一个对我有用的不错的简单选择是:

<a href="javascript: false" onClick={this.handlerName}>Click Me</a>

这太低估了。如果你不介意的话,我想吻你。先生,你从很多事情上救了我。对于表单元素action="javascript: false"也起作用。
OzgurBagci

1
@OzgurBagci使用以上方法将在最新版本的React中引发警告。它可能现在可以使用,但可能无法长期使用。最好找到替代方法,尤其是在使用最新版本的React时。
David

1

这是因为这些处理程序不保留范围。从反应文档:反应文档

检查“无自动绑定”部分。您应该像这样编写处理程序:onClick =()=> {}


1

我发现并为我工作的要点:

const DummyLink = ({onClick, children, props}) => (
    <a href="#" onClick={evt => {
        evt.preventDefault();
        onClick && onClick();
    }} {...props}>
        {children}
    </a>
);

感谢srph https://gist.github.com/srph/020b5c02dd489f30bfc59138b7c39b53


1
我可以建议不要将其onClick用作传递的prop函数名称,而应使用类似的名称handleClick?这令人困惑,其他经验不足的开发人员可能认为这是组件的实际附加事件,而事实并非如此。另外,即使组件接收相同的道具,每次重新渲染组件时,您都将创建一个新函数。这被认为是不好的做法。
elQueFaltaba

0

如果使用复选框

<input 
    type='checkbox'
    onChange={this.checkboxHandler}
/>

stopPropagationstopImmediatePropagation将不起作用。

因为您必须使用onClick = {this.checkboxHandler}


0

如果您使用的是React Router,我建议您查看一下具有方便组件LinkContainer的react-router-bootstrap库。此组件可防止默认页面重新加载,因此您不必处理该事件。

在您的情况下,它可能类似于:

import { LinkContainer } from 'react-router-bootstrap';

<LinkContainer to={givePathHere}>
    <span className="upvotes" onClick={this.upvote}>upvote</span>
</LinkContainer>

0

preventDefault过去,我在使用锚标签时遇到了一些麻烦,而我总是忘记自己做错了什么,所以这就是我的想法。

我经常遇到的问题是,我试图像其他React组件一样直接通过分解它们来访问组件的属性。这将不起作用,页面将重新加载,即使使用e.preventDefault()

function (e, { href }) {
  e.preventDefault();
  // Do something with href
}
...
<a href="/foobar" onClick={clickHndl}>Go to Foobar</a>

似乎Cannot read property 'href' of undefined是因为页面完全重新加载,所以解构会导致错误()没有显示在控制台上。由于该函数有错误,因此preventDefault不会被调用。如果href为#,则由于没有实际重新加载,因此错误显示正确。

我现在知道,我只能在自定义React组件上访问属性作为第二个处理程序参数,而不能在本地HTML标签上访问。因此,当然,要在事件中访问HTML标记属性,可以采用以下方式:

function (e) {
  e.preventDefault();
  const { href } = e.target;
  // Do something with href
}
...
<a href="/foobar" onClick={clickHndl}>Go to Foobar</a>

我希望这可以帮助像我这样的其他人为未显示的错误感到困惑!


0

当我进入此页面时,我发现上述任何选项都不正确或不适合我。他们确实给了我一些测试的想法,我发现这对我有用。

dontGoToLink(e) {
  e.preventDefault();
 }

render() {
  return (<a href="test.com" onClick={this.dontGoToLink} />});
}

0

这些方法都不适合我,所以我只用CSS解决了这个问题:

.upvotes:before {
   content:"";
   float: left;
   width: 100%;
   height: 100%;
   position: absolute;
   left: 0;
   top: 0;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.