【问题标题】:How to pass variables to a function reference?如何将变量传递给函数引用?
【发布时间】:2018-11-10 20:33:28
【问题描述】:

在 react native 中,当您有需要在渲染时运行并且必须传递变量的函数时,大多数人建议应该使用

onPress{() => this.functionName(variable)}

但是,在处理大型列表和复杂组件时,您必须优化代码。为flatList 中的每个renderItem 创建一个新函数会降低性能,有时会大大降低性能,具体取决于您创建的每个renderItem 有多少个函数。所以建议是从在渲染时创建函数转向使用函数引用。像这样:

functionName = () => {
   //code
}

onPress={this.functionName}

但是我无法弄清楚如何使用这种方法将变量传递给函数。

如果你这样做:

onPress={this.functionName(variable}

它只会在组件加载时立即运行该功能。

有什么想法吗?

【问题讨论】:

  • 你从哪里得到这个变量?

标签: javascript reactjs function react-native


【解决方案1】:

我强烈推荐使用 currying 来传递参数。

柯里化是将一个函数分成几个函数的过程,每个函数都接受一个参数。在这种情况下,这个方法工作得很好的原因是当你在 render 方法上调用一个函数时,传递的参数自动是event,所以要传递第二个参数,函数必须是 curried 以便接收下一个参数。

你可以这样定义你的函数:

functionName = variable => event => {
 //code 
}

然后你可以继续在 render 方法中调用你的函数:

onPress={this.functionName(variable)}

如果您想了解更多信息,这是一篇很棒的文章: Currying In JS

这个方法非常优雅和有用,因为它不需要将你的函数调用包装在 React 的 render 方法中的匿名函数中。

在任何其他情况下,您也可以按照官方 React Docs 的建议进行操作: React Docs on passing arguments to event handlers

祝你好运!

【讨论】:

  • 出于好奇,使用这样的柯里化函数会阻止它在此处的每个渲染中创建吗?我认为没有。我真的很喜欢柯里化,但对于这个问题,我认为它并不能解决 OP 的问题。
  • @devserkan 是正确的,这将重新声明每个渲染的函数。您可以在下面找到我的答案,以了解在不进行柯里化的情况下不重新声明函数的方法:stackoverflow.com/questions/50630902/…
  • 很高兴知道我也想知道。这篇文章的重点是避免在渲染上重新创建一个函数,这会产生性能问题,并且在某些情况下会使浅层比较变得更加困难。但是我确实需要了解 currying,所以我会看看,谢谢你的信息!
  • 通过 Render Props 使用闭包的有趣方法:reactjs.org/docs/render-props.html
【解决方案2】:

正如Esther Cuan 建议的那样,柯里化是要走的路。如果您使用依赖于变量更改的动态创建的函数,则很有可能。那么创建这些函数所花费的时间远少于每次变量更改时重新渲染组件所花费的时间。效率方面,优先级应该是尽量减少变量变化,以便在函数不断重新定义之前很久就尽量减少重新渲染。

但是,如果您确定某些功能是一致的,即使是通过重新渲染,并且不希望它们被重新声明,您可以通过以下方式实现:

class Component extends React.Component {
  functionName = (e) => {
    const { variable } = this.props
    // run logic on the event and variable
  } 

  render() {
    // some code
    onPress={this.functionName}
  }
}

您会注意到这种方法 functionName 只声明一次。

这种方法的性能缺陷是,现在您必须创建另一个组件(可能还有类附带的生命周期方法)才能将variable 作为道具传递,从而绕过对柯里化的需求。

【讨论】:

  • 这种讨论总是以“过度优化”结束:) 我喜欢完全避免在处理程序上使用绑定或箭头函数。是的,创建新组件可能会更加困难,编写它们,测试它们,为它们记录。但是,嘿,我只是一个爱好者而不是专业人士:)
【解决方案3】:

在您的构造函数中(或只要variable 可用),您可以只预绑定一次函数:

this.handle_press = this.functionName.bind(this, variable);

【讨论】:

  • 如果您在构造函数之外执行此操作,这不会限制this 的范围吗?
  • 只要将function.bind(this_obj)指向正确的对象,那么正确的this就会出现在绑定函数内部。根据你是在一个胖箭头函数() => {} 还是一个函数表达式function() {} 中,你提供给function.bind() 的第一个参数可能不一定与当前运行的函数中的this 相同,如果这有意义的话.
【解决方案4】:

我正在写这个答案作为一个学习者。所以它可能需要一些澄清。当我开始使用 JS 和 React 编写代码时,我遇到了这个问题(感谢 linter)并进行了一些搜索以了解最佳实践。但是,我找不到像这样直接使用变量的任何优化方法。对于这些情况我会做什么:

  • 如果我正在渲染项目列表,我会按照这里的建议创建自己的组件:react/jsx-no-bind 所以,传递一个回调函数和变量,完成这项工作并使用这个回调函数。是的,这里有一些工作,创建了一堆处理函数。但是,如果这是优化的方式,那么弄脏我的手不是问题。

  • 如果变量处于状态或来自props,则不需要像这样在onClick方法上使用它。在处理函数中我们可以访问这个变量。

【讨论】:

  • 你使用 refs 来传递变量?我的印象是根本不应该使用 refs。我确定在某些情况下您必须这样做,但我只遇到过 textinput 方法。你的技术可以吗?
  • 我真的很努力,但我不记得我在哪里使用它。我很确定我用过它,但我不记得怎么用了。我已经从我的问题中删除了这部分,因为它不会误导人们。因为如果有输入,就可能有状态,所以不需要使用 refs。你是对的,不应该经常使用 refs。至少正如 React 官方文档所说:“不要过度使用 Refs”:)
【解决方案5】:

您可以将variable 作为该元素的值参数传递,例如

<button
 value={variable}
 onPress={this.functionName}>
 click
</button>

然后你可以“拾取”那个变量:

fuctionName = e => {
 const yourVariable = e.target.value;
 // now you have access to your variable through the const declaration
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多