skip to Main Content

I am new to react typescript. I am searching for hours and no solution.
I have a json object saved inside of file categories.ts like

const categories = [
  {value: "Farsi", label: "fa"},
  {value: "English", label: "en"},
  {value: "Hindi", label: "hi"},
  {value: "Spanish", label: "es"},
  {value: "French", label: "fr"},
  {value: "Japanese", label: "ja"},
  {value: "Russian", label: "ru"},
  {value: "German", label: "de"},
  {value: "Italian", label: "it"},
  {value: "Korean", label: "ko"},
  {value: "Brazilian Portuguese", label: "pt-BR"},
  {value: "Arabic", label: "ar"},
  {value: "Turkish", label: "tr"}
];

export default categories;

This is the code I am working which is saved inside a utility file called useDictionary.ts

    import { useState, useEffect } from "react";
    import categories from "../data/categories";
    
    type dataCategoryType = {
      value: string;
      label: string;
    }
    
    const useDictionary = () => {
        
        const [category, setCategory] = useState<dataCategoryType[]>([]);

        // setCategory(<dataCategoryType[]> JSON.parse(categories));
     const cat: DataCategoryType = <dataCategoryType[]> JSON.parse(categories);
    setCategory(cat);

   return {
        category
    };
    
    export default useDictionary;

the error is

Argument of type '{ value: string; label: string; }[]' is not assignable to parameter of type 'string'.ts(2345)
(alias) const categories: {
    value: string;
    label: string;
}[]
import categories

can you please tell me the proper way of seasoned typescript folks do this?
Please also note the returned value category is passed to APP component. like

const { category } = useDictionary();

Many thanks in advance,

2

Answers


  1. I had to make my comment to be an answer.

    The first thing wrong with your code is that you are treating categories as a JSON whereas it is an Object (javascript ARRAY), so, JSON.parse would keep throwing an error, and get rid of the parse, meaning the code needs to look like this.

    import { useState, useEffect } from "react";
    import categories from "../data/categories";
    
    type dataCategoryType = {
        value: string;
        label: string;
    }
    
    const useDictionary = () => {
        const [category, setCategory] = useState<dataCategoryType[]>([]);
        const cat: dataCategoryType = categories;
        setCategory(cat);
    
        return {
            category
        };
    }
    
    export default useDictionary;
    

    Now we’ve fixed that, if you are going to set the category state (that you already have before hand), you can do that directly on the useState initialization.

    const [category, setCategory] = useState<dataCategoryType[]>(categories);
    

    and get rid of the cat variable and the setCategory beneath that, final code should look like this.

    import { useState, useEffect } from "react";
    import categories from "../data/categories";
    
    type dataCategoryType = {
        value: string;
        label: string;
    }
    
    const useDictionary = () => {
        const [category, setCategory] = useState<dataCategoryType[]>(categories); // set the initial value to be our categories array
    
        return {
            category
        };
    }
    
    export default useDictionary;
    
    Login or Signup to reply.
  2. Issue:

    • JSON.parse is used to convert json from string. But your data exported from categories.ts file is already an array. so no need to parse it.
    • As the categories is a const, we can easily initialize the hook state with this value. no need to initialize the state with empty array first and then call setState to store data.

    Updated Code:

    import { useState, useEffect } from "react";
    import categories from "../data/categories";
    
    type dataCategoryType = {
    value: string;
    label: string;
    }
    
    type UseDictionaryType = {
    categories: dataCategoryType[];
    }
    
    const useDictionary = (): UseDictionaryType => {
        
    const [category, setCategory] = useState<dataCategoryType[]>(categories);
    
    return { category };
    
    }
        
    export default useDictionary;
    

    You can also provide a return type for useDictionary hook. Normally we also return the setCategory here from the hook so that we can update the categories from outside of this hook. But it depends on your use case also.

    Let me know if it helps.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search