为什么 HTML 不允许我以与 JSX 相同的方式添加事件处理程序?

Val*_*ery 1 javascript function reactjs

为什么这段代码在React JSX 中有效,但在HTML中无效:

下面的代码只是标签的一个属性 . 一个函数handleClick只显示console.log

此代码适用于React JSX代码:

onClick={() => this.props.handleClick(1)}
Run Code Online (Sandbox Code Playgroud)

这在HTML 中不起作用:

onclick={() => handleClick(1)}
Run Code Online (Sandbox Code Playgroud)
  1. 为什么我应该将handleClick函数放在 React JSX 的另一个函数中?
  2. 为什么它在HTML 中不起作用?

Dai*_*Dai 5

  • ReactJS 有自己的 JSX 解释器/编译器,这就是它的工作方式。
  • 在“VanillaJS”(实际上,只是JavaScript)中,您无法获得这种好处。
    • 除非您想将 JSX 引擎导入您的 JS 项目并处理这些依赖项。

为什么我应该将handleClick函数放在 React JSX 中的另一个函数中?

我需要更多上下文来回答这个问题。

为什么它在 HTML 中不起作用?

onclick={() => handleClick(1)}
Run Code Online (Sandbox Code Playgroud)

这在 VanillaJS 中不起作用,因为它onclick是一个函数属性,但您可以简单地onclick用新函数覆盖函数属性:

someButton.onclick = () => handleClick(1); // Warning: this will replace any existing `onclick` function property.
Run Code Online (Sandbox Code Playgroud)

事实上,这就是 JavaScript 程序员在将多个事件处理程序addEventListener添加到 DOM之前向同一个事件添加多个事件处理程序的方式,并且支持变得广泛(大约在 2000 年代后期):

var currentOnClick = someButton.onclick;
someButton.onclick = function( e ) {
    if( currentOnClick ) currentOnClick( e );
    // do stuff 
};
Run Code Online (Sandbox Code Playgroud)

当然官方的方式是使用DOM的addEventListener函数:

someButton.addEventListener( 'click', handleClick.bind(this) );
// or:
someButton.addEventListener( 'click', () => handleClick(1) );
// or:
someButton.addEventListener( 'click', e => handleClick(1) );
Run Code Online (Sandbox Code Playgroud)

如果你想让 JavaScript 的事件处理代码更简洁,那么 patch EventTarget( 的父类型addEventListener):

Object.defineProperty( EventTarget.prototype, 'onclick2', {

    get() {
        if( typeof this.onclickHandlers == 'undefined' ) {
           this.onclickHandlers = [];
        }
        return this.onclickHandlers;
    }

    set( handlerFunc ) {

        if( typeof this.onclickHandlers == 'undefined' ) {
           this.onclickHandlers = [];
        }

        this.onclickHandlers.push( handlerFunc );

        this.addEventListener( 'click', handlerFunc );
    }

} );
Run Code Online (Sandbox Code Playgroud)

用法:

someButton.onclick2 = () => doSomething();
Run Code Online (Sandbox Code Playgroud)