我有这个小的自定义钩子,它返回一个Object.assign
结果。在文档中,它说这将返回一个数组,但是下面的示例可用于数组解构和对象解构。
代码:
import { useState } from 'react';
const useStateExtended = (initialValue, initialLoading = false) => {
const [data, setData] = useState(initialValue);
const [loading, setLoading] = useState(initialLoading);
return Object.assign([data, setData, loading, setLoading], { data, setData, loading, setLoading })
};
export default useStateExtended;
此代码可以通过以下方式使用:
const {data, setData, loading, setLoading} = useStateExtended({});
const [data, setData, loading, setLoading] = useStateExtended({});
这是如何工作的?为什么我要像数组和对象一样对它们进行破坏?
第二:如何在Typescript中输入?数据类型为:
data: any;
setData: (data: any) => void;
loading: boolean;
setLoading: (boolean) => void;
答案 0 :(得分:4)
您可以在带有迭代器的任何对象(包括数组)上使用方括号分解。
您可以对任何对象(数组是对象)使用大括号分解。
这样做的时候
Object.assign([data, setData, loading, setLoading], { data, setData, loading, setLoading })
您创建了一个既具有普通数组索引[0]
,[1]
,又具有 属性.data
,.setData
等的数组。这在Javascript中非常奇怪,但是由于数组是对象,并且由于对象可以分配有任意键-值对,所以这是合法的。
因此,您可以使用[
解构从对象中检索属性,调用数组的迭代器,或者使用{
解构调用,从对象中检索命名属性。对象。
也就是说,这不是您应该要做的,因为(正如您的问题所表明的那样),这是令人困惑的发生的事情,而可读性可能是代码的最重要因素。数组绝不应该具有任意的键/值对(正则表达式匹配的情况除外,在这种情况下,附加属性由解释器本身生成)。
要键入它,请对initialValue
的类型使用泛型,以便可以将其传递给useState
,并声明数组as const
,以使数组解构检索出正确的类型。正确的顺序:
const useStateExtended = <T extends unknown>(initialValue: T, initialLoading = false) => {
const [data, setData] = useState<T>(initialValue);
const [loading, setLoading] = useState(initialLoading);
return Object.assign([data, setData, loading, setLoading] as const, { data, setData, loading, setLoading })
};