如何在useCallback钩子中传递参数?

4

我正在尝试使用useCallback钩子来改变语言,使用gatsby-intl插件,它们有一个方法(changeLocale())可以用于更改网站的默认语言。我想避免在JSX箭头函数中传递props(虽然这个解决方案可行),因此我正在尝试使用useCallback钩子。

onClick={()=>switchLanguage(language.iso)}

这是我的组件:

import React, { useCallback, useState } from 'react';
import { changeLocale } from 'gatsby-plugin-intl';
import { useLanguages } from '../../../hooks/useLanguages';

export const LanguageSwitcher = (callback, deps) => {
  const languages = useLanguages();

  const switchLanguage = useCallback(language => changeLocale(language),[]);

  return <ul>
    {languages.map((language, index) => <li key={index} onClick={switchLanguage(language.iso)}>{language.name}</li>)}
  </ul>;

};

上面的代码创建了一个无限渲染,代码在没有点击 switchLanguage 函数的情况下进入。
然而,如果我删除参数,它会按预期工作,但是我不知道用户点击的语言是什么。
  const switchLanguage = useCallback(()=> console.log('item clicked'),[]);

我还尝试使用其他钩子(hooks),例如useState,但它会创建太多的渲染。

我如何将参数传递给useCallback?如果不可能,哪种是最好的解决方法或方法?

1个回答

4

onClick={switchLanguage(language.iso)} 调用 switchLanguage 并将其返回值设置为 onClick,就像在JSX之外使用onClick = switchLanguage(language.iso)一样。

要将参数绑定到它上面,您需要使用包装函数:

onClick={() => switchLanguage(language.iso)}

...或者 bind,但是它也会创建一个函数:

onClick={switchLanguage.bind(null, language.iso)}

但是:在您的示例中使用useCallback可能没有太多可获得的好处。如果情况如此,您可能根本不需要switchLanguage

import React, { useCallback, useState } from 'react';
import { changeLocale } from 'gatsby-plugin-intl';
import { useLanguages } from '../../../hooks/useLanguages';

export const LanguageSwitcher = (callback, deps) => {
  const languages = useLanguages();

  return <ul>
    {languages.map((language, index) => <li key={index} onClick={() => changeLocale(language.iso)}>{language.name}</li>)}
  </ul>;
};

谢谢您的回复!是的,那是我的第一种方法,但我想避免直接在JSX属性上绑定函数。我想我的唯一选择是使用类似这样的东西:const switchLanguage = (language) => changeLocale(language); 并在 onClick 事件中调用 switchLanguage - Ferran Buireu
1
@FerranBuireu - 看起来这是现今相当标准的做法。需要记住的是,每次组件渲染时,您仍在重新创建函数,只是有时您不使用该新函数。React hooks 的一个基本假设似乎是创建函数非常快。 (我知道现代引擎会在函数实例之间重用代码,因此它应该基本上像创建对象一样快。) - T.J. Crowder
1
@FerranBuireu - "我想我的唯一选择就是使用这样的东西:const switchLanguage = (language) => changeLocale(language);,然后调用switchLanguage。" 我认为在那个时候没有什么理由使用 switchLanguage,对吧?或者它除了调用 changeLocale 还有其他作用吗? - T.J. Crowder
最好保持简单,直接在JSX上绑定而不是创建一个无用的函数,我想。谢谢你的大师课程。 - Ferran Buireu
1
@FerranBuireu - 哈哈,开什么玩笑。 :-) 很高兴能帮忙!祝编码愉快。 - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接