在React Hooks中,点击事件的语法是什么以传递参数?

11

在 React 类组件中,这对我总是很有效:

let myValue: string = "Hello World";
<Button onClick={this.handleClick.bind(this, myValue)}></Button>

我在 React Hooks 文档中发现了这个语法,我很喜欢它,但它并不总是返回一个值:

<Button onClick={handleClick} value={myValue}></Button>

这种语法是可行的,但难以输入且看起来很凌乱:

<Button onClick={() => handleClick(myValue)}></Button>

这是另一种适用于钩子的方法,但对我来说似乎有些欺骗性。

  <Button onClick={handleClick.bind(null, myValue)}></Button>

我对太多的选择感到困惑。难道没有最佳实践的方法吗?


2
  1. 不建议在事件函数中使用 lambda 表达式。
  2. myValue 是从哪里来的,你想将其作为函数参数传递?如果它来自状态,你是否想把它作为参数使用?
- Amir-Mousavi
1
该问题缺乏上下文,没有提到myValue的来源。 - Estus Flask
@estus - 我添加了一些代码以澄清myValue的来源。 - Lambert
@Lambert 我明白了,我更新了答案来涵盖这个问题。 - Estus Flask
2个回答

18

这是完全适合做这件事的方法:

<Button onClick={() => handleClick(myValue)}></Button>
唯一的缺点是 onClick 属性在每次渲染时都有一个新值,并触发子组件重新渲染 - 即使它是纯的。这可能会或可能不会导致性能问题,具体取决于特定的组件;如果有许多 Button 实例或它们的重新渲染很昂贵,那么这将是一个问题。

如果一个值是静态的,可以将回调定义为组件外的常量函数:

// outside function component
const myValue = "Hello World";
const myHandleClick = () => handleClick(myValue);
...
// inside function component
<Button onClick={myHandleClick}></Button>

如果一个值是动态的,且仅在组件内可用,则可以在组件内定义一个函数,并使用useMemouseCallback hook进行记忆化(正如另一个回答已经提到的那样):

// inside function component
const myHandleClick = useCallback(() => handleClick(myValue), [myValue]);
...
<Button onClick={myHandleClick}></Button>

6
在你的问题中,第一个和最后一个版本都创建了一个新函数。因此,如果你可以仅将函数 handleClick 分配给一个属性,那么你应该这样做。如果你需要将参数传递给函数,则仍然可以在函数组件中使用你的第一个版本,但是由于未使用 this,因此可以将其设置为 null
<Button onClick={handleClick.bind(null, myValue)}></Button>

这是你在 hooks 组件中的做法,也是你推荐的吗? - Lambert
2
如果我需要创建一个新函数来传递一些参数,我个人会使用() => handleClick(myValue),但是这两种方法之间的差异微不足道。这主要是品味问题。 - Tholle
@Thule - 但是Amir说“在事件函数中使用lambda表达式不被推荐”,这是怎么回事?难道你的个人选择不这样做吗? - Lambert
@Lambert 我不同意“不建议在事件函数中使用lambda表达式”的说法。我不明白为什么会这样。 - Tholle
这是一种更简单、更好的方法。 - sumit
谢谢,我的情况也可以使用这种技术:在我的情况下,我只想将对象传递给函数,以便我可以访问其数据。 `const columns = React.useMemo( () => [ { Header: '内容列表', columns: [ { Header: '标题/文件名', accessor: 'content_title_filename', Cell: ({row})=> <a href={row.original.content_url} onClick={AccessResource.bind(row,null)}>{row.values.content_title_filename</a>} }, ..function AccessResource() { alert('传递了名称->' + this.original.content_title_filename);}` - Robert Walters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接