Usage of Async await with hooks

278 views Asked by At

I have a simple translation function that takes one parameter(string) and return string. It works fine when i use like await translation(key) how ever my need it to use it frequently inside in react native component like below

<Text>{tranlate("faqs")}</Text>

Then again somewhere

<Button title={translate("terms")}/>

My question is although its a async function and not trigger without await or then/catch block. What could be other way i can simple use it without await or then/catch because using it like below is not working

<Text>{await translate("faqs")}</Text>

Any help would be really appriciated!Thanks

2

There are 2 answers

17
DecPK On BEST ANSWER

It's better to create a custom hook which takes key as input and return translated key.

You shouldn't use async-await in (J|T)SX.

CODESANDBOX

So it can also be used in multiple components

const _cache = {};

function useTranslate(key) {
  const [state, setState] = useState(key);

  useEffect(() => {
    (async () => {
      try {
        // IF PROMISE RESOLVED THEN GET TRANSLATED VALUE
        const cachedValue = _cache[key];
        if (!cachedValue) {
          const translatedValue = await translate(key);
          _cache[key] = translatedValue;
          setState(translatedValue);
        } else setState(cachedValue);
      } catch (error) {
        console.log(error);
      }
    })();
  }, [key]);

  // IF VALUE IS TRANSLATED THEN IT WILL RETURN VALUE
  // ELSE RETURN KEY AS A FALLBACK VALUE
  return state;
}

export default function App() {
  const translateFAQ = useTranslate("faqs");
  return (
    <div className="App">
      <Text>{translateFAQ}</Text>
    </div>
  );
}
3
Ali Nauman On

You can use a simple custom hook that will return you the translated text:

import { useEffect, useState } from "react";

// Your translate function
const translate = async (str) => {
  return str;
};

export const useTranslate = (str) => {
  const [translatedText, setTranslatedText] = useState(null);

  useEffect(() => {
    const getTranslation = async () => {
      const result = await translate(str);
      setTranslatedText(result);
    };

    getTranslation();
  }, [str]);

  return translatedText;
};

This can then be consumed in a component like this:

const translatedText = useTranslate('abc')

return (
  <Text>{translatedText}</Text>
)