React onClick and preventDefault () ссылка на обновление / перенаправление?

87

Я делаю ссылку с реакцией:

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)

return false - не работает.

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

Я также пробовал все вышеперечисленное, используя jQuery в моем index.html, но, похоже, ничего не работает. Что мне здесь делать и что делаю не так? Я проверил event.type, clickтак что, думаю, мне удастся как-то избежать перенаправления?

Извините, я новичок, когда дело касается React.

Спасибо!

Wordpressor
источник
1
вы пытаетесь использовать синтаксис es2015 для функций?
erichardson30
Какие компоненты вы создаете? Без гражданства? createClass?
markthethomas
Можете ли вы подтвердить, что onClick действительно работает upvote? Это может быть проблема контекста.
thangngoc89
1
ИспользованиеpreventDefault
onmyway133 04
1
Только e.PreventDefault () работал у меня (React 16.0.0-beta5)
felix-b

Ответы:

70

События React на самом деле являются синтетическими, а не собственными событиями. Как здесь написано :

Делегирование событий: React фактически не присоединяет обработчики событий к самим узлам. Когда React запускается, он начинает прослушивать все события на верхнем уровне, используя один прослушиватель событий. Когда компонент монтируется или размонтируется, обработчики событий просто добавляются или удаляются из внутреннего сопоставления. Когда происходит событие, React знает, как отправить его с помощью этого сопоставления. Когда в сопоставлении не осталось обработчиков событий, обработчики событий React не работают.

Попробуйте использовать Используйте Event.stopImmediatePropagation:

upvote: (e) ->
  e.stopPropagation();
  e.nativeEvent.stopImmediatePropagation();
Александр Лазарев
источник
74

Полная версия решения будет заключать метод upvotes внутри 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 (); в начале или в конце функции? Где больше смысла размещать?
Сартерис Штормхаммер
Я думаю, что лучше использовать вначале
Роман
Это плохая практика, ознакомьтесь с функциями стрелок и .bind(this)контекстом bin в приложении для реагирования. Например: medium.freecodecamp.org/…
Joyful
за исключением того, что это просто создание функции для передачи аргумента. Если вы уже используете реакцию и ES6, вам не нужна функция с областью действия. И вы могли бы так же легко сделать это, связав его с this в конструкторе.
Iwnnay
Помните, что если вы активируете рендеринг (например, изменив состояние) до вызова e.preventDefault (), это не даст никакого эффекта. Так что лучше сделать его первым оператором обработчика событий.
Thim Anneessens
16

попробуйте bind (this), чтобы ваш код выглядел, как показано ниже -

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

или если вы пишете компонент реагирования es6 в конструкторе, вы можете сделать это

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

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

}
дипак пракаш
источник
9
Это не имеет значения. Вы получаете положительные голоса, потому что у людей есть thisобработчик событий, и у них совершенно другая проблема.
Димитар Несторов
8

визуализировать: -> <a className="upvotes" onClick={(e) => {this.upvote(e); }}>upvote</a>

xjinjin
источник
1
Это плохая практика, ознакомьтесь с функциями стрелок и .bind(this)контекстом bin в приложении для реагирования. Например: medium.freecodecamp.org/…
Joyful
createReactClass или Autobinding или используйте пакет npm 'auto-bind'
xjinjin
7

В таком контексте

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.
Дэвид
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в качестве переданного имени функции опоры, а использовать что-то вроде handleClickэтого? Это сбивает с толку, другие менее опытные разработчики могут подумать, что это фактическое присоединенное к компоненту событие, хотя это не так. Кроме того, при этом вы создаете новую функцию каждый раз при повторном рендеринге компонента, даже если он получает те же свойства. Это считается плохой практикой.
elQueFaltaba
0

Если вы используете флажок

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

stopPropagation и stopImmediatePropagation не будут работать.

Потому что вы должны использовать onClick = {this.checkboxHandler}

Роман
источник
0

Если вы используете React Router, я бы посоветовал изучить библиотеку react-router-bootstrap, в которой есть удобный компонент LinkContainer. Этот компонент предотвращает перезагрузку страницы по умолчанию, поэтому вам не нужно иметь дело с событием.

В вашем случае это может выглядеть примерно так:

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>

Надеюсь, это поможет другим людям вроде меня озадачиться непоказанными ошибками!

DSav
источник
0

Когда я зашел на эту страницу, я не обнаружил, что ни один из упомянутых вариантов является правильным или работает для меня. Они действительно дали мне идеи для проверки, и я обнаружил, что это сработало для меня.

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

render() {
  return (<a href="test.com" onClick={this.dontGoToLink} />});
}
Iwnnay
источник
0

точно так же, как чистый js do preventdefault: в классе вам нужно создать метод обработчика:

handler(event) {
    event.preventDefault();
    console.log(event);
}
киараш шамайи
источник
-1

ни один из этих методов у меня не сработал, поэтому я решил это с помощью CSS:

.upvotes:before {
   content:"";
   float: left;
   width: 100%;
   height: 100%;
   position: absolute;
   left: 0;
   top: 0;
}
Суат Агез
источник