【问题标题】:Multiple functions inside onClick with a ternary and referenceonClick 中的多个函数,带有三元和引用
【发布时间】:2021-06-06 21:23:39
【问题描述】:

这是一个我想在 JSX 中更好地理解语法的例子。

问题:

这行得通:

<button
  onClick={ !isRecording ? beginRecording : endRecording } > 
</button>

这很有效:

<button
  onClick={ () => { modalPortal.current.open() } } > 
</button>

<Modal ref={modalPortal}>
    <h1>Congratulations!</h1> 
    <p>If this modal opened, you find javascript syntax seamless and intuitive</p>
</Modal>

在一起,没有bueno。

<button
    onClick={!isRecording ? () => {modalPortal.current.open();beginRecording} : endRecording } > 
</button>

错误:

react-expected-an-assignment-or-function-call-and-instead-saw-an-expression


详情:

这是在函数组件内部。 isRecording & endRecording 等是定义我在应用程序中所在页面的功能组件范围内的对象中的状态,modalPortal 是参考:

export default function RecordPage() 
{
    let [audioURL, isRecording, beginRecording, endRecording, timer] = RecorderContext(); 
    const modalPortal = useRef(null);
...
}

我还尝试了将其传递给执行条件评估等的单个函数的各种排列

onClick={ doManyThings() } > 

无论有无箭头,无论是括号还是传入参数,如果没有,似乎都不起作用。我希望有知识的人给出明确的答案!


对我尝试过但不起作用的事情的引用:

Conditional onClick from ternary

Call multiple functions onClick ReactJS

Setting conditional onClick behaviour in React Component

React: Expected an assignment or function call and instead saw an expression

【问题讨论】:

  • 如果要使用第二种语法,请使用 beginRecording()endRecording()。您不能像这样混合和匹配函数调用和函数引用。或者,只是有一个封装三元的函数,并停止在视图中执行条件逻辑。
  • 你只需要做onClick={ () =&gt; doManyThings() }
  • @Yadab - 试过了 - 不,确实是缺少括号。我还不明白为什么将它们放在一个上下文中并在另一个上下文中神秘地停止编译器在语法上是有效的
  • 函数名只是对该函数的引用,即doManyThings,当您添加括号doManyThings()时,您正在调用该函数。 onClick={doManyThings} 在功能上几乎等同于 onClick={() =&gt; doManyThings()}。在 React 中的许多情况下,你会看到括号被丢弃有几个原因:(1) onClick 回调不关心点击事件,(2) 回调不需要传递任何参数。跨度>

标签: javascript reactjs jsx


【解决方案1】:

您可以将三元/分支逻辑移动到单个回调函数中。

<button
  onClick={() => {
    if (!isRecording) {
      modalPortal.current.open();
      beginRecording();
    } else {
      endRecording();
    }
  }
>
  ...
</button>

如果您想继续使用三元,尽管您还需要调用beginRecording 函数。这里的想法是类似的,根据条件,返回一个做一些事情的匿名函数,或者返回一个函数引用来做任何 it 所做的事情。

<button
  onClick={!isRecording 
    ? () => {
        modalPortal.current.open();
        beginRecording(); // <-- also invoke
      } 
    : endRecording
  } 
>
  ... 
</button>

【讨论】:

  • 德鲁,我可以吻你。在过去的两个小时里,我差点把笔记本电脑扔出窗外。这个投票率很高的答案(表明只能使用三元组)非常具有误导性:stackoverflow.com/a/45573716/12137312
  • 啊,感谢编辑为答案添加更多上下文。
  • 让我感到愤怒的是,在我提出的尝试中,成功与失败之间的区别实际上是添加到函数调用中的括号。只需将括号添加到 beginRecording() 即可修复它。
  • @lys 有趣的是,其他答案似乎解决了 linting 警告/错误,但它似乎在回答不同的问题/问题。在我看来,三元组的提及似乎是事后才想到的,但无论哪种方式,如果您没有意识到每个案例隐含返回的内容仍然需要根据其自身的优点而有效,我可以看到这可能会导致您误入歧途。跨度>
  • @lys 是的,语法可能很棘手(而且很重要!)。 ?
【解决方案2】:

试试这个:

const handleButtonClick = () => {
  if (isRecording) {
    endRecording()
    return
  }

  modalPortal.current.open()
  beginRecording()
}


<button onClick={handleButtonClick} />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-16
    • 2021-11-23
    • 2017-12-14
    • 2014-01-19
    • 2021-10-24
    • 2019-07-15
    • 1970-01-01
    • 2021-04-22
    相关资源
    最近更新 更多