Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an argument in useCallback hook?

I'm trying to use the useCallback hook, to change the language using gatsby-intl plugin, they have a method (changeLocale()) what can be used to change the default language of the site. I wanted to avoid passing props in JSX arrow's functions despite the solution is working so I'm trying to use the useCallback hook.

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

Here's my component:

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

};

The code above creates an infinite rendering, the code is entering on switchLanguage function without clicking it.

However, if I remove the argument, it works as expected but I don't know what language is the user clicking.

  const switchLanguage = useCallback(()=> console.log('item clicked'),[]);

I've also tried to use other hooks such as useState but it creates too many renders.

How can I pass an argument to the useCallback? If it is not possible, which will be the best workaround or approach?

like image 973
Ferran Buireu Avatar asked Nov 16 '25 22:11

Ferran Buireu


1 Answers

onClick={switchLanguage(language.iso)} calls switchLanguage and sets its return value as onClick, just like onClick = switchLanguage(language.iso) would outside JSX.

To bind the argument to it, you'd use a wrapper function:

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

...or bind, though it also creates a function:

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

But: There's probably not much to be gained by using useCallback in your example. That being the case, you probably don't need switchLanguage at all:

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>;
};
like image 174
T.J. Crowder Avatar answered Nov 18 '25 13:11

T.J. Crowder