javascript - 将自定义 Hook 注入(inject) evolve 函数的优雅方式

标签 javascript reactjs functional-programming react-hooks ramda.js

我和我的团队每天都在大力整合 FP 和 React-hooks 模式,尽管有时我们会为如何将 hooks 与纯函数一起管理而苦恼。最近,我们遇到了很多情况,其中钩子(Hook)“回调”必须位于 compose 或另一个转换器内的某个地方——在这种情况下,它是 evolve 函数,例如:

const getDefinedActions = R.filter(
      R.both(isActionDefined, R.ifElse(hasAfterConfirm, isAfterConfirmDefined, R.T))
    )
    
const translateTitles = R.map(
  R.evolve({
    title: title => useTranslate()(title)
  })
)

export const useActions = R.compose(
  translateTitles,
  getDefinedActions
)

在上面的示例中,我们希望根据一些谓词过滤掉操作并添加翻译,这需要使用 useTranslate Hook 。不幸的是,我们不能在那里写 useTranslate(),因为必须在挂载 React 组件后初始化 Hook 。到目前为止在这些情况下做了什么:

  • “即时”创建 Hook 函数,并将其传递给另一个 ramda 的函数。例如 { const translate = useTranslate(); return R.compose(..., translate, ...) } - 我们不喜欢这种方法,因为在执行此操作时我们无法合并无点样式;/

  • 另一种方法是在匿名函数中调用 hook,方法与我在上面的代码片段中所写的相同。 - 虽然我们不必编写整个功能 block 并声明一个额外的变量,但我们也不喜欢这种方法,因为我们觉得我们总是不得不冗余地编写传递过来的参数:arg = > 钩子(Hook)()(参数)

在 FP 中是否有任何通用方法来处理我们必须注入(inject)函数的问题,该函数必须被延迟评估,然后我们可以根据该结果进行其他计算?甚至 Ramda 本身也有帮助注入(inject)特定行为的功能,所以我们可以这样使用它:

R.evolve({
  title: R.useWith(useTranslate, R.identity) // arg => useTranslate()(R.identity(arg))
})

附言。我知道 Ramda 中有一个名为 useWith 的函数,但它以不同的方式工作;/

我们将不胜感激任何帮助!

最佳答案

我不确定我是否完全理解您的问题。您是否只是在寻找一种仅对 useTranslate 进行初始化的方法?如果是这样,那么我不认为 Ramda 有任何内置的东西,但是写一些像

这样的东西就足够容易了
const dethunk = (fn) => {
  let initialized = null;
  return (...args) => (initialized || (initialized = fn())) (...args)
}

然后写一些类似的东西。

const translateTitles = map (evolve ({title: dethunk(useTranslate) }))

如果您想将参数传递给初始化,您可以将其更改为

const dethunk = (fn, ...initialArgs) => {
  let initialized = null;
  return (...args) => (initialized || (initialized = fn(...initialArgs))) (...args)
}

const foo = (a, b) => {
  console.log(`Initializing with '${a}' and '${b}'`)
  return (c) => `foo('${a}', '${b}', ${c})`
}

const bar = dethunk(foo, 'x', 'y')

console.log('Have not initialized yet');

console .log (bar (1))
console .log (bar (2))
console .log (bar (3))

这是否满足您的需求?

关于javascript - 将自定义 Hook 注入(inject) evolve 函数的优雅方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58155062/

相关文章:

java - Applet JSObject javascript 调用是否序列化?

javascript - React - 切换相邻元素的颜色

javascript - node.js 中使用 lodash 的部分类方法?

functional-programming - Racket - 构建内置成员函数

javascript - 使用MatterJS防止通过其他物体拖拉物体

javascript - 在函数后面查找 $(this)

javascript - 如何在调用函数之前检查回调函数的参数数量

javascript - 如何在 React 的嵌套组件场景中使页脚居中对齐

reactjs - 如何使用 React 和 Material UI 控制另一个模块的对话框

typescript - 如何在 Typescript 4 中编写 curry 和 compose?