JS Lodash - 如何用 _.curry() 重构柯里化函数?

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

简介

我有这个代码:

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>
  );
}

然后,我决定使用柯里化函数重构它。像这样:

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>
  );
}

如您所见,我调用方法的方式发生了变化,因为我返回的是一个函数,而不是 myMethod 中的 void。太棒了,它有效...每次按下按钮时,都会调用我的方法。

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

问题

现在,我正在尝试使用 curry from Lodash 重构重构代码。

这是我试过的:

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>
  );
}

但由于某种原因,这不起作用。该方法不会在每次按下按钮时执行...而是在组件挂载时调用。

我该如何解决?

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

恐怕您误解了 currying(这很容易做到,而且很多人都误解了 — 包括我自己)。

Then, I decided to refactor it using curried functions. Like this:

该代码没有柯里化函数。它只是在 name 参数上创建一个闭包。那叫partial application.

Lodash 的 curry 改为柯里化。函数 it returns 将在其所有参数都得到满足后立即开始工作——在您的情况下,只要您为其提供所需的名称。因此,当您执行 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>

如果你想让它等待第二个参数,你需要告诉 curry 你的函数需要两个参数,然后为它提供两个参数(在这种情况下一次一个):

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>

这是可行的,因为我们已经告诉 curry 你的函数需要有两个参数,而 myMethod("Victor") 只给了它一个,所以它 returns 另一个函数可以完成它的工作当你给它另一个论点时。 onPress 将给它第二个参数,因为它将事件对象传递给它。

查看 curry 文档以获取更多示例。

也就是说,我不会在这里使用 curry。您并不是真正的柯里化,所以这有点误用。如果我必须将名称烘焙到函数中,我会使用您的部分应用程序解决方案。