如何将数据从自定义钩子传递到组件?

huangapple go评论65阅读模式
英文:

How can I pass data from custom hook to component?

问题

以下是代码部分的翻译:

我有一个自定义钩子它将参数数据与获取的数据传递给组件 Settings在那里我在 useEffect 中有一个名为 setData11 的钩子我想在该钩子中设置来自 useTable 的数据但我遇到错误

&gt; 类型参数'数据|列[]|未定义'无法分配给类型参数'SetStateAction <DataTable [] | 未定义> '
  类型'Data'无法分配给类型'SetStateAction <DataTable [] | 未定义> '
    类型'Data'缺少类型'DataTable []'的以下属性lengthpoppushconcat  29 个属性ts(2345)

接口 DataTable {
  [id: string | number]: string | number;
}

接口 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 <></>;
}

这是你提供的代码的翻译部分,如果你有任何进一步的问题或需要更多的帮助,请随时告诉我。

英文:

I have custom hook which pass parameter data with fetched data to component Settings. There I have hook setData11 in useEffect and I want to set in that hook data passed from useTable but I get error

> 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[] = [
&quot;https://jsonplaceholder.typicode.com/posts&quot;,
&quot;https://jsonplaceholder.typicode.com/comments&quot;,
&quot;https://jsonplaceholder.typicode.com/albums&quot;,
&quot;https://jsonplaceholder.typicode.com/photos&quot;,
&quot;https://jsonplaceholder.typicode.com/todos&quot;,
];
const useTable = (idurl: number, actualcategory: string) =&gt; {
const [data, setData] = useState&lt;Data&gt;();
const [columns, setColumns] = useState&lt;Column[]&gt;();
const loadDatabase = () =&gt; {
fetch(urls[idurl])
.then((response) =&gt; response.json())
.then((response) =&gt; {
setData({
...data,
new: response.filter((t: DataTable[], i: number) =&gt; {
return i &gt; 50 &amp;&amp; i &lt; 100 &amp;&amp; t;
}),
removed: response.filter((t: DataTable[], i: number) =&gt; {
return i &gt; 100 &amp;&amp; i &lt; 150 &amp;&amp; t;
}),
postponed: response.filter((t: DataTable[], i: number) =&gt; {
return i &gt; 50 &amp;&amp; i &lt; 100 &amp;&amp; t;
}),
});
const objcolumn: Column[] = Object.keys(response[0]).map(
(t: string) =&gt; {
let d: Column = { col: { title: t, disp: true } };
return d;
}
);
setColumns(objcolumn);
});
};
useEffect(() =&gt; {
loadDatabase();
alert(JSON.stringify(data));
}, []);
return [data, columns];
};
export { useTable };
const Settings = () =&gt; { 
const [data, columns, checkall, changeDatabase] = useTable(1, &quot;new&quot;);  
const[ data1, setData1]=useState&lt;DataTable[]&gt;()
useEffect(() =&gt; {
setData1(data) 
}, []);
return &lt;&gt;&lt;/&gt;
}

答案1

得分: 1

以下是您要翻译的内容:

"It's not clear to me what this code is supposed to do, so it's difficult to give you a specific answer.

Your example contains several mistakes.

The first one can be confusing. When you return an array from your custom hook, its type will be inferred as Array&lt;Data | Column[]&gt;. If you want to get a signature similar to useState, you should use as const to tell TypeScript that this array contains a specific number of elements in a specific order and cannot change.

But even after you specify as const, TypeScript will complain about two things:

  1. The number of elements that you are trying to unpack from useTable should correspond to the two that you are returning (possibly just a typo). So it's should be const [data, columns] = useTable(...)
  2. The type Data | undefined and DataTable[] | undefined are incompatible, which is entirely true. I'm not entirely sure what your end goal is. If you want to use a specific category as the data1 state, you should pass some attribute of data
const useTable = (idurl: number, actualcategory: string) => {
  ...
  return [data, columns] as const; // use "as const"
};

// --------------

const Settings = () => { 
  // Remove extra parameters
  const [data, columns] = useTable(1, "new");  

  const [data1, setData1] = useState<DataTable[]>()

  useEffect(() => {
    // data also can be undefined, so you need to use ?. syntax
    setData1(data?.SOME_CATEGORY) 
  }, []);
 
  return <></>;
}
英文:

It's not clear to me what this code is supposed to do, so it's difficult to give you a specific answer.

Your example contains several mistakes.

The first one can be confusing. When you return an array from your custom hook, its type will be inferred as Array&lt;Data | Column[]&gt;. If you want to get a signature similar to useState, you should use as const to tell TypeScript that this array contains a specific number of elements in a specific order and cannot change.

But even after you specify as const, TypeScript will complain about two things:

  1. The number of elements that you are trying to unpack from useTable should correspond to the two that you are returning (possibly just a typo). So it's should be const [data, columns] = useTable(...)
  2. The type Data | undefined and DataTable[] | undefined are incompatible, which is entirely true. I'm not entirely sure what your end goal is. If you want to use a specific category as the data1 state, you should pass some attribute of data
const useTable = (idurl: number, actualcategory: string) =&gt; {
  ...
  return [data, columns] as const; // use &quot;as const&quot;
};

// --------------

const Settings = () =&gt; { 
  // Remove extra parameters
  const [data, columns] = useTable(1, &quot;new&quot;);  


  const [data1, setData1] = useState&lt;DataTable[]&gt;()

  useEffect(() =&gt; {
    // data also can be undefined, so you need to use ?. syntax
    setData1(data?.SOME_CATEGORY) 
  }, []);
 
  return &lt;&gt;&lt;/&gt;
}

答案2

得分: 0

感谢回答 如何将数据从自定义钩子传递到组件?

这是问题的解决方案

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

英文:

thanks for answer 如何将数据从自定义钩子传递到组件?

here is resolution of the problem

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

huangapple
  • 本文由 发表于 2023年2月19日 21:34:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75500495.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定