Jak przekazac dane z wlasnego hook-a ?

0

Witam,

mam custom hook useTable , w ktorym wczytuje dane z api i przekazuje te dane do komponentu, ale one sa jakos niezrozumiale dla mnie formatowane. Hook setData1 w Settings nie moze wczytac przekazanych danych data i daje nastepujacy blad

Argument of type 'Data | Column[] | undefined' is not assignable to parameter of type 'SetStateAction<DataTable[] | undefined>'. Type 'Data' is not assignable to type 'SetStateAction<DataTable[] | undefined>'. Type 'Data' is missing the following properties from type 'DataTable[]': length, pop, push, concat, and 29 more.ts(2345)
interface DataTable {
  [id: string | number]: string | number;
}

interface Data {
  [category: string]: DataTable[];
}

const urls: string[] = [
  "https://jsonplaceholder.typicode.com/posts",
  "https://jsonplaceholder.typicode.com/comments",
  "https://jsonplaceholder.typicode.com/albums",
  "https://jsonplaceholder.typicode.com/photos",
  "https://jsonplaceholder.typicode.com/todos",
];

const useTable = (idurl: number, actualcategory: string) => {
  const [data, setData] = useState<Data>();

  const [columns, setColumns] = useState<Column[]>();
  const loadDatabase = () => {
    fetch(urls[idurl])
      .then((response) => response.json())
      .then((response) => {
        setData({
          ...data,
          new: response.filter((t: DataTable[], i: number) => {
            return i > 50 && i < 100 && t;
          }),

          removed: response.filter((t: DataTable[], i: number) => {
            return i > 100 && i < 150 && t;
          }),

          postponed: response.filter((t: DataTable[], i: number) => {
            return i > 50 && i < 100 && t;
          }),
        });
        const objcolumn: Column[] = Object.keys(response[0]).map(
          (t: string) => {
            let d: Column = { col: { title: t, disp: true } };
            return d;
          }
        );
        setColumns(objcolumn);
      });
  };
  useEffect(() => {
    loadDatabase();
    alert(JSON.stringify(data));
  }, []);
  return [data, columns];
};

export { useTable };

const Settings = () => { 
  const [data, columns, checkall, changeDatabase] = useTable(1, "new");  

  const[ data1, setData1]=useState<DataTable[]>()
    useEffect(() => {
      setData1(data) 
    }, []);
   
  return <></>
}
1

po pierwsze TypeScript zainferował niezgodnie z twoimi intencjami. Ponieważ useTable zwraca [data, columns], to TypeScript myśli, że zwracany typ to (Data | Column[] | undefined)[], czyli tablica, która zawiera elementy o typie może Data może Column[] a może undefined.

Więc to co możesz zrobić, to dodać deklarację zwracanego typu jako tuple [Data | undefined, Column[] | undefined]:

const useTable = (idurl: number, actualcategory: string):  [Data | undefined, Column[] | undefined] => {

ale dalej będziesz miał błędy, po pierwsze jakiś stary kod masz:

const [data, columns, checkall, changeDatabase] = useTable(1, "new");  

checkall i changeDatabase w ogóle nie jest zwracane przecież.

poza tym też krzyczy, że masz typ stanu DataTable[] a próbujesz tam władować data, który ma inny typ:

  useEffect(() => {
    setData1(data) 
  }, []);

^ po moich poprawkach dalej tu masz błąd Argument of type 'Data | undefined' is not assignable to parameter of type 'SetStateAction<DataTable[] | undefined>'. ale nie wiem co chciałeś osiągnąć dokładnie.

0

dzieki

1

inny sposob to zrobic return type as const

return [data, columns] as const

tutaj material https://fettblog.eu/typescript-react-typeing-custom-hooks/

1 użytkowników online, w tym zalogowanych: 0, gości: 1