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?
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>;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With