简体   繁体   English

JS Lodash - 如何用 _.curry() 重构 curried function?

[英]JS Lodash - How to refactor a curried function with _.curry()?

Introduction介绍

I had this code:我有这段代码:

import React, { Component } from 'react';
import { View, Button } from 'react-native';

export default function App() {
  const myMethod = (name) => {
    console.log(`Hello ${name}!`);
  };

  return (
    <View>
      <Button onPress={() => myMethod("Victor")}>
        Press me!
      </Button>
    </View>
  );
}

Then, I decided to refactor it using curried functions.然后,我决定使用柯里化函数重构它。 Like this:像这样:

import React, { Component } from 'react';
import { View, Button } from 'react-native';

export default function App() {
  /**
   * @param {string} name - The name.
   * @returns {Function} Curried function.
   */
  const myMethod = (name) => {
    return () => {
      console.log(`Hello ${name}!`);
    }
  };

  return (
    <View>
      <Button onPress={myMethod("Victor")}>
        Press me!
      </Button>
    </View>
  );
}

As you can see, the way I am invoking the method has changed, as I am returning a function instead of void in myMethod .如您所见,我调用该方法的方式发生了变化,因为我在myMethod中返回了 function 而不是void That's cool, it works... every time the button is pressed, my method is invoked.太棒了,它起作用了……每次按下按钮时,都会调用我的方法。

Check this snack: https://snack.expo.dev/Rx3iBVT_W检查这个小吃: https://snack.expo.dev/Rx3iBVT_W

Problem问题

Now, I am trying to refactor the refactored code using curry from Lodash .现在,我正在尝试使用Lodash 中的curry重构重构代码。

This is what I have tried:这是我试过的:

import React, { Component } from 'react';
import { View, Button } from 'react-native';
import { curry } from 'lodash';

export default function App() {
  const myMethod = curry((name) => {
    console.log(`Hello ${name}!`);
  });

  return (
    <View>
      <Button onPress={myMethod("Victor")}>
        Press me!
      </Button>
    </View>
  );
}

But for some reason, this is not working.但由于某种原因,这是行不通的。 The method is not executed every time the button is pressed... Instead, it is invoked when the component mounts.该方法不会在每次按下按钮时执行...而是在组件安装时调用。

How can I solve it?我该如何解决?

Check this snack: https://snack.expo.dev/bna6cLkhp检查这个小吃: https://snack.expo.dev/bna6cLkhp

I'm afraid you've misunderstood currying (which is easily done, and lots have — including myself).恐怕您误解了柯里化(这很容易做到,而且很多人都有——包括我自己)。

Then, I decided to refactor it using curried functions.然后,我决定使用柯里化函数重构它。 Like this:像这样:

That code doesn't curry a function. It just creates a closure over the name parameter.该代码不会柯里化 function。它只是在name参数上创建一个闭包。 That's called partial application .这就是所谓的部分应用

Lodash's curry does currying instead. Lodash 的curry代替咖喱。 The function it returns will do its work as soon as all of its parameters are satisfied — as soon as you provide it the name it needs, in your case.它返回的 function 将在满足所有参数后立即开始工作——在你的情况下,只要你提供它需要的名称。 So it does its work when you do myMethod("Victor") , not later:因此,当您执行myMethod("Victor")时它会起作用,而不是稍后:

 const myMethod = _.curry((name) => { console.log(`Hello ${name};`); }); myMethod("Victor");
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

If you want it to wait for a second argument, you need to tell curry that your function requires two arguments, and then provide it with two arguments (one at a time in this case):如果你想让它等待第二个参数,你需要告诉curry你的 function 需要两个 arguments,然后给它提供两个 arguments(在这种情况下一次一个):

 const myMethod = _.curry((name) => { console.log(`Hello ${name};`), }; 2), // ^−−−−−−− tells `curry` this function needs two arguments. even // though the function itself says it only needs 1 console;log("Supplying the first argument"); const fn = myMethod("Victor"). console;log("Supplying the second argument"); fn({}), // <== Note the argument, we need to supply one
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

That works because we've told curry your function needs to have two arguments, and myMethod("Victor") only gives it one, so it returns another function that will do its work when you give it the other argument.这是有效的,因为我们已经告诉curry你的 function 需要有两个 arguments,而myMethod("Victor")只给它一个,所以它返回另一个 function,当你给它另一个参数时它会完成它的工作。 onPress will give it a second argument because it passes the event object to it. onPress会给它第二个参数,因为它将事件 object 传递给它。

Check out the curry documentation for more examples.查看curry文档以获取更多示例。

That said, I wouldn't use curry here.也就是说,我不会在这里使用curry You're not really currying, so it's a bit of a misuse.您并不是真正的柯里化,所以这有点误用。 I'd use your partial application solution, if I had to bake the name into the function at all.如果我必须将名称写入 function,我会使用您的部分应用程序解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM