Search code examples
reactjstypescriptreact-typescripttsx

How to create interface for array of objects in usestate in react js


I made a request with AXIOS to the server and then the server returned the value as follows:

enter image description here

I want to save it in state, here I use react hooks, when I want to set state with data as shown I get error:

Argument of type '() => IterableIterator<IMahasiswa>' is not assignable to parameter of type 'SetStateAction<undefined>'.
  Type 'IterableIterator<IMahasiswa>' is not assignable to type 'undefined'.ts(2345)

and this is my code:

enter image description here

and my interface:

enter image description here

how do I set the interface for setMahasiswa I have tried <IMahasiswa[]> but it gives the same error, except that in the res.values ​​section it is replaced with res it is successfully returned, but it will throw another error when I using map for looping


Solution

  • My assumption is that your axios.get(url[, config]) returns an any type by default. So, your data there also has any type unless you cast it to IMahasiswa[].

    However, my suggested solution is to define the type at axios.get, here's the outline from their typedef.

    export interface AxiosInstance {
      //...
      get<T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R>;
      //...
    }
    

    Therefore, you can do something like this;

    await axiosClient.get<IMahasiswa[]>("asd/asd", {});
    

    Here's the full code example;

    interface IMahasiswa {
      name: string;
      age: number;
    }
    
    const useTest = () => ({
      async fetch(): Promise<IMahasiswa[]> {
        const { data } = await axiosClient.get<IMahasiswa[]>("asd/asd", {});
        return data; // data here has the type of IMahasiswa[]
      },
    });
    
    const axiosClient = axios.create({
      baseURL: "http://localhost:1231",
    });
    
    const TestComp = () => {
      const [mahasiswa, setMahasiswa] = React.useState<IMahasiswa[]>([]);
      const testFn = useTest();
    
      useEffect(() => {
        testFn.fetch().then((res) => {
          setMahasiswa(res);
        });
      }, []);
    
      return <div>asd</div>;
    };