React Hook“useTranslation”在函数“getMyMenu”中调用,该函数既不是 React 函数组件,也不是自定义 React Hook 函数

tes*_*dtv 3 javascript reactjs react-hooks

useTranslation从正常函数中调用钩子,如下所示

import { useTranslation } from "react-i18next";


function getMyMenu(a) {
  const { t } = useTranslation('translations');
  
  if (a.showRoute) {
      a.label = t(a.label);
    return a;
  }
}



export const MyNav = props => {
  let tabs = recurseFn(getMyMenu, props.routes);
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误。难道就没有办法解决这个问题吗?由于一些奇怪的原因,我能够看到类似的代码模式在其他项目中工作。需要任何额外的配置才能使其工作吗?

更新:

这就是我的recurseFn样子:

export const recurseFn = (chk, [head, ...tail]) => {
  if (head === undefined) return [];
  if (chk(head)) {
    return [head, ...recurseFn(chk, tail)];
  }

  return [...recurseFn(chk, tail)];
};
Run Code Online (Sandbox Code Playgroud)

Dre*_*ese 5

useTranslation您可以通过将钩子移动到MyNav组件主体并将翻译函数t作为闭包传递来修复它getMyMenu

import { useTranslation } from "react-i18next";

export const MyNav = props => {
  const { t } = useTranslation('translations');

  function getMyMenu(a) {
    if (a.showRoute) {
      a.label = t(a.label);
      return a;
    }
  }

  let tabs = recurseFn(getMyMenu, props.routes);

  ...
}
Run Code Online (Sandbox Code Playgroud)

编辑

我刚刚更新了我的recurseFn样子。是否可以将“t”传递给它?

解决方案 1 -t显式传递给所有函数

您当然可以更新 的函数签名以recurseFn也使用“t”(翻译?)函数,但是您仍然需要传递t给它chk,这将需要更新原始getMyMenu函数以使用附加参数。

例子:

function getMyMenu(t, a) { // <-- consume additional t argument
  if (a.showRoute) {
      a.label = t(a.label);
    return a;
  }
}

...

export const recurseFn = (chk, [head, ...tail], t) => { // <-- consume additional t argument
  if (head === undefined) return [];
  if (chk(t, head)) { // <-- pass t to chk
    return [head, ...recurseFn(chk, tail, t)]; // <-- pass t on recursion
  }

  return [...recurseFn(chk, tail, t)]; // <-- pass t on recursion
};

...

import { useTranslation } from "react-i18next";

export const MyNav = props => {
  const { t } = useTranslation('translations');

  let tabs = recurseFn(getMyMenu, props.routes, t); // <-- pass t on recursion

  ...
}
Run Code Online (Sandbox Code Playgroud)

解决方案 2 - 使用柯里化回调的更好解决方案

在这种情况下,我认为制作getMyMenu一个柯里化函数可以帮助您将t回调括起来,并允许它在任何 React 组件的外部声明。该recurseFn函数不需要了解有关 的任何信息t,那么为什么要在那里公开它,对吗?

const getMyMenu = t => a => {
  if (a.showRoute) {
    a.label = t(a.label);
    return a;
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以tuseTranslation钩子返回值进行解构并传递给柯里化getMyMenu函数。t这与关闭回调中的函数类似,就像我们在第一个答案中所做的那样。

import { useTranslation } from "react-i18next";

export const MyNav = props => {
  const { t } = useTranslation('translations');

  let tabs = recurseFn(getMyMenu(t), props.routes);

  ...
}
Run Code Online (Sandbox Code Playgroud)

现在从recurseFn的角度来看,t包含在chk回调中,recurseFn不需要显式处理接收和传递t