6

I need to populate a select input with a large list of countries. Because of internationalization, I have a separate json file for each language available. In order not to load all of them in my component, I would like to only import the one corresponding to the current locale.

Here is what I wrote:

function MyComponent() {
  const [countries, setCountries] = useState([]);
    const { locale } = useLocale();
  
  useEffect(() => {
    import(`../../data/countries/${locale}.json`)
      .then((res) => setCountries(res.countries))
      .catch(_ => null);
  }, []);
  
  return <Select options={countries}/>
  }

I also thought about writing my own hook in a separate file:

export const useFetchJSON = (file: string) => {
  const [data, setData] = useState({});
  const { locale } = useLocale();
  const res = require(`../data/${file}/${locale}.json`);
  setData(res);
  return data;
};

None of this techniques work. How to fix this? Thanks!

2
  • What error are you getting? Commented Dec 12, 2020 at 23:00
  • Try to add a console.log inside catch block Commented Dec 12, 2020 at 23:14

1 Answer 1

9

If you are not getting any error you can get the json data with res.default:

 useEffect(() => {
    import(`../../data/countries/${locale}.json`)
      .then((res) => setCountries(res.default.countries))
      .catch(_ => null);
  }, []);

If you are getting this error:

Module ./.json not declared as a System.registerDynamic dependency of

You should check your module bundle configuration.

Other solutions:

1.create an object to store the import functions:

const LocalesData = {
  en_AU: () => import("../../data/countries/en_AU.json"),
  es_ES: () => import("../../data/countries/es_ES.json"),
  //...
};

useEffect(() => {
  LocalesData[locale]()
    .then(res => console.log(res.default))
    .catch(_ => console.log("res", _));
}, []);

2. Move the static files to public folder and load the data using fetch:

  useEffect(() => {
    fetch(`${locale}.json`)
      .then(res => res.json())
      .then(res => console.log(res))
      .catch(_ => console.log(_));
  }, []);
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.