Làm mới / chuyển hướng liên kết onClick và PreventDefault ()?


84

Tôi đang hiển thị một liên kết với phản ứng:

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

Sau đó, ở trên tôi có chức năng ủng hộ:

upvote: ->
  // do stuff (ajax)

Trước liên kết, tôi đã mở rộng ở nơi đó nhưng tôi cần chuyển sang liên kết và đây là vấn đề - mỗi khi tôi nhấp vào .upvotestrang được làm mới, những gì tôi đã thử cho đến nay:

event.preventDefault () - không hoạt động.

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

event.stopPropagation () - không hoạt động.

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

trả về false - không hoạt động.

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

Tôi cũng đã thử tất cả các cách trên bằng cách sử dụng jQuery trong index.html của mình, nhưng dường như không có gì hoạt động. Tôi nên làm gì ở đây và tôi đang làm gì sai? Tôi đã kiểm tra event.type và nó clicknên tôi đoán bằng cách nào đó tôi có thể tránh chuyển hướng?

Xin lỗi, tôi là một tân binh khi nói đến React.

Cảm ơn bạn!


1
bạn đang cố gắng sử dụng cú pháp es2015 cho các chức năng?
erichardson

Bạn đang tạo loại thành phần nào? Không quốc tịch? createClass?
markthethomas

Bạn có thể xác nhận rằng onClick đang thực sự tấn công upvotekhông? Đây có thể là một vấn đề bối cảnh.
thangngoc89

1
Sử dụngpreventDefault
onmyway133

1
e.PreventDefault () một mình làm việc cho tôi (React 16.0.0-beta5)
felix-b

Câu trả lời:


67

Sự kiện React thực sự là Sự kiện tổng hợp, không phải Sự kiện gốc. Như nó được viết ở đây :

Ủy quyền sự kiện: React không thực sự đính kèm các trình xử lý sự kiện vào chính các nút. Khi React khởi động, nó bắt đầu lắng nghe tất cả các sự kiện ở cấp cao nhất bằng cách sử dụng một trình nghe sự kiện duy nhất. Khi một thành phần được gắn kết hoặc không được gắn kết, trình xử lý sự kiện chỉ được thêm vào hoặc xóa khỏi ánh xạ nội bộ. Khi một sự kiện xảy ra, React biết cách gửi nó bằng cách sử dụng ánh xạ này. Khi không có trình xử lý sự kiện nào còn lại trong ánh xạ, trình xử lý sự kiện của React rất đơn giản.

Cố gắng sử dụng Sử dụng Event.stopImmediatePropagation:

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

74

Một phiên bản đầy đủ của giải pháp sẽ bao gồm phương thức tán thành bên trong onClick, chuyển e và sử dụng bản địa 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>);
{

Có sự khác biệt giữa e.preventDefault (); đang ăn xin hoặc kết thúc chức năng? Đặt nó ở đâu có ý nghĩa hơn?
Sartheris Stormhammer,

Tôi nghĩ rằng đó là tốt hơn để sử dụng nó trong đầu
La Mã

Đó là cách làm không tốt, vui lòng đọc về các hàm mũi tên và .bind(this)ngữ cảnh bin trong ứng dụng phản ứng. Ví dụ: medium.freecodecamp.org/…
Joyful

ngoại trừ đây chỉ là tạo một hàm để truyền đối số. Nếu bạn đang sử dụng react và ES6 rồi, bạn không cần đến chức năng phạm vi. Và bạn có thể dễ dàng thực hiện điều đó bằng cách liên kết nó với điều này trong hàm tạo.
Iwnnay

Hãy lưu ý rằng nếu bạn kích hoạt hiển thị (ví dụ: bằng cách thay đổi trạng thái) trước khi gọi e.preventDefault () thì nó sẽ không có tác dụng. Vì vậy, tốt hơn nên có nó như là câu lệnh đầu tiên của trình xử lý sự kiện.
Thim Anneessens

16

hãy thử bind (cái này) để mã của bạn trông giống như bên dưới:

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

hoặc nếu bạn đang viết trong thành phần phản ứng es6 trong hàm tạo, bạn có thể làm điều này

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

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

}

9
Điều này không có gì khác biệt. Bạn đang nhận được sự ủng hộ vì mọi người có thistrong trình xử lý sự kiện của họ và có một vấn đề hoàn toàn khác.
Dimitar Nestorov

8

kết xuất: -> <a className="upvotes" onClick={(e) => {this.upvote(e); }}>upvote</a>


1
Đó là cách làm không tốt, vui lòng đọc về các hàm mũi tên và .bind(this)ngữ cảnh bin trong ứng dụng phản ứng. Ví dụ: medium.freecodecamp.org/…
Joyful

createReactClass hoặc Autobinding hoặc sử dụng gói npm 'auto-bind'
xjinjin

6

Trong bối cảnh như thế này

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

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

Như bạn có thể thấy, bạn phải gọi PreventDefault () một cách rõ ràng. Tôi nghĩ rằng tài liệu này , có thể hữu ích.


2

Một lựa chọn hay và đơn giản phù hợp với tôi là:

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

điều này được đánh giá quá thấp. Tôi muốn hôn bạn nếu bạn không phiền. bạn đã cứu tôi khỏi rất nhiều thứ thưa ông. cho phần tử biểu mẫu action="javascript: false"cũng đang hoạt động.
OzgurBagci

1
@OzgurBagci Sử dụng phương pháp trên sẽ đưa ra các cảnh báo trong React trong các phiên bản mới hơn. Nó có thể hoạt động ngay bây giờ, nhưng có thể sẽ không hoạt động lâu dài. Có lẽ tốt nhất nên tìm một phương pháp thay thế, đặc biệt nếu sử dụng phiên bản React mới hơn.
David

1

Điều này là do những trình xử lý đó không bảo toàn phạm vi. Từ tài liệu phản ứng : tài liệu phản ứng

Kiểm tra phần "không có tự động". Bạn nên viết trình xử lý như: onClick = () => {}


1

Gist tôi đã tìm thấy và làm việc cho tôi:

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

Tín dụng cho srph https://gist.github.com/srph/020b5c02dd489f30bfc59138b7c39b53


1
Tôi có thể đề nghị không sử dụng onClickdưới dạng tên hàm prop đã truyền mà handleClickthay vào đó là một cái gì đó giống như vậy không? Thật khó hiểu, các nhà phát triển ít kinh nghiệm khác có thể nghĩ rằng đó là sự kiện thực sự được đính kèm với thành phần, trong khi không phải vậy. Ngoài ra, với điều này, bạn đang tạo một chức năng mới mỗi khi thành phần hiển thị lại, ngay cả khi nó nhận được cùng một đạo cụ. Nó được coi là một thực hành xấu.
elQueFaltaba

0

Nếu bạn sử dụng hộp kiểm

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

stopPropagationstopIm InstantPropagation sẽ không hoạt động.

Vì bạn phải sử dụng onClick = {this.checkboxHandler}


0

Nếu bạn đang sử dụng React Router, tôi khuyên bạn nên xem xét thư viện react-router-bootstrap có chứa thành phần LinkContainer tiện dụng. Thành phần này ngăn tải lại trang mặc định để bạn không phải đối phó với sự kiện.

Trong trường hợp của bạn, nó có thể trông giống như sau:

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

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

0

Tôi đã gặp một số rắc rối với thẻ neo và preventDefaulttrong quá khứ và tôi luôn quên mình đang làm gì sai, vì vậy đây là những gì tôi đã tìm ra.

Vấn đề tôi thường gặp phải là tôi cố gắng truy cập các thuộc tính của thành phần bằng cách hủy cấu trúc chúng trực tiếp như với các thành phần React khác. Điều này sẽ không hoạt động, trang sẽ tải lại , ngay cả với e.preventDefault():

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

Có vẻ như cấu trúc hủy gây ra lỗi ( Cannot read property 'href' of undefined) không được hiển thị trên bảng điều khiển, có thể do tải lại trang hoàn chỉnh. Vì hàm bị lỗi, hàm preventDefaultkhông được gọi. Nếu href là #, lỗi được hiển thị đúng vì không có tải lại thực tế.

Bây giờ tôi hiểu rằng tôi chỉ có thể truy cập các thuộc tính dưới dạng đối số xử lý thứ hai trên các thành phần React tùy chỉnh, không phải trên các thẻ HTML gốc . Vì vậy, tất nhiên, để truy cập thuộc tính thẻ HTML trong một sự kiện, đây sẽ là cách:

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

Tôi hy vọng điều này sẽ giúp những người khác giống như tôi đang bối rối bởi lỗi không hiển thị!


0

Tôi không tìm thấy bất kỳ tùy chọn nào được đề cập là chính xác hoặc phù hợp với tôi khi tôi truy cập trang này. Họ đã cho tôi ý tưởng để kiểm tra mọi thứ và tôi thấy rằng điều này hiệu quả với tôi.

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

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

0

không có phương pháp nào trong số này hiệu quả với tôi, vì vậy tôi chỉ giải quyết vấn đề này bằng CSS:

.upvotes:before {
   content:"";
   float: left;
   width: 100%;
   height: 100%;
   position: absolute;
   left: 0;
   top: 0;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.