代码之家  ›  专栏  ›  技术社区  ›  IPSDSILVA

React OnClick事件不传递参数,而是传递SyntheticBaseEvent

  •  0
  • IPSDSILVA  · 技术社区  · 7 月前

    我正在创建一个模态。当6中的任何一个打开时,此模式将打开 div 元素被点击。每个组件都是使用 .map() 函数到数组。这个 popup 参数应该是单击时运行的函数:

    items.map(item => (
      <StoreItem popup={() => popup} item={item} />
    ))         
    

    对于每一个 item items ,有一个 StoreItem 创建。这是的代码 店铺项目 组件:

    const StoreItem = ({popup, item}) => {
      return (
        <div onClick={popup(item)} className="...">
        ...
        </div>
      );
    };
    

    如上所述,每个 店铺项目 是a div 与A onClick 运行的属性 popup() 功能。这是 弹出窗口() 功能:

    function popup(item) {
        console.log(item);
    }
    

    出于某种原因,当我 console.log(item) ,the 项目 这应该是从 单击 未被记录。相反,我得到了一个 SyntheticBaseEvent 随机的东西,我不想要。

    这是如何固定的,以便内容 项目 正确显示,而不是一些 综合基础事件 ?

    谢谢,任何帮助都不胜感激。

    2 回复  |  直到 7 月前
        1
  •  1
  •   isqua    7 月前

    要使其工作,您应该稍微摇动括号:

    // No parentheses here in the popup props
    items.map(item => (
      <StoreItem popup={popup} item={item} />
    ))
    
    const StoreItem = ({popup, item}) => {
      // But create a new arrow function here
      return (
        <div onClick={() => popup(item)} className="...">
        ...
        </div>
      );
    };
    

    这不是一个特定于反应的问题,这就是函数在JavaScript中的工作方式。让我解释一些细节

    如何调用函数

    所以,你创建了一个函数

    function popup(item) {
        console.log(item);
    }
    

    为了让它记录一些东西,我们应该 呼叫 函数和传递某物作为 参数 ,就像这样:

    popup("hello")
    

    上面的代码记录 "hello" ,因为我们调用了函数( 在函数名后写括号 )并通过了 “你好” 字符串作为它的参数。

    但是,如果不在函数名称后写括号,则可以将函数视为 变量 。例如,您可以将一个函数分配给一个新变量:

    const meow = popup
    
    popup("hello") // it logs "hello"
    meow("hello") // it logs "hello", because it calls the same function, just by a different name
    

    让我们看看你的代码是如何工作的

    查看渲染项目的代码

    items.map(item => (
      <StoreItem popup={() => popup} item={item} />
    ))  
    

    在这里,您可以创建一个新的箭头函数 () => popup .功能 不接受 任何参数(括号为空),以及 退货 这个 popup 功能。但同样,它没有调用 弹出窗口 功能,对吗?因为我们在单词后面没有看到任何括号 弹出窗口 .

    然后,在渲染单个项目时,您不会创建新函数,而是 呼叫 你会得到什么作为弹出属性:

    const StoreItem = ({popup, item}) => {
      return (
        <div onClick={popup(item)} className="...">
        ...
        </div>
      );
    };
    

    所以,在 弹出窗口 属性你得到你在父组件中创建的函数,对吧:

    () => popup
    

    现在,当传递到 onClick 财产,你终于 呼叫

    onClick={popup(item)}
    

    正确的所以你打电话给 ()=>弹出窗口 具有 item 作为一个参数。但是 ()=>弹出窗口 功能 不接受 任何参数。但它会归还你的原件 function popup 因此,该代码等效于以下内容:

    onClick={function popup(x) {
        console.log(x);
    }}
    

    如您所见,该函数只接受一个参数,对您的“item”变量一无所知。我有意将其命名为“x”,以表明变量的名称无关紧要。该函数只记录其参数是什么,而不是一些外部作用域变量。

    因此,当您单击元素时,react会捕获事件并将事件传递给您的函数。

    如果你想更深入地理解这个话题,你可以读一些关于“高阶函数”的文章。

        2
  •  1
  •   PsiKai    7 月前

    React正在将事件对象传递给你的函数,你不能通过将参数命名为其他名称来控制它。

    您要做的是将匿名函数传递给 onClick ,你在其中打电话 popup(item) .

    <div onClick={() => popup(item)} className="...">
    

    React仍然会将事件对象传递给函数,但你忽略了这一点,因为你没有将其包含在函数定义中。然后在函数体中执行on逻辑,即调用 popup 功能与 item .

    这就是正在发生的事情,请注意,您对事件什么也不做,但无论如何,它都将是该函数的第一个参数。

    <div onClick={(event: SyntheticBaseEvent) => popup(item)} className="...">