最近,我试图重新考虑我在应用程序中使用的状态结构,但我遇到了一些困难,不知道如何继续下去。
首先,我使用了下面的redux状态结构:
type State = {
loading: boolean
loaded: boolean
items: Array<Item>
categories: Array<Category>
}
const initialState: State = {
loading: false,
loaded: false,
items: [],
categories: [],
}
它简单且易于与选择器一起使用,并且因为items
和categories
的类型始终保持相同,因此无需担心未定义或强制转换类型。但是我需要添加一些额外的属性,我只需要几次和干燥来为每个redux动作创建一个单独的类型,现在我有了这个:
type RequestItems = {
category: Category;
items: Array<Item>;
totalCountFromServer: number;
}
export type RequestItem = {
item: Item;
}
export type RequestCategories = {
categories: Array<Category>
}
type RequestContent =
| RequestItem
| RequestItems
| RequestCategories
type State = {
loading: boolean;
loaded: boolean;
content: RequestContent | undefined
}
这种结构不那么冗余,但我不确定useSelector是否可以确定extact类型,或者是否有比这更好的方法来使用它:
我认为在这里使用状态钩子有点多余,但是我可以检查内容幻灯片是否“欠精确”,如果是,则返回“404”。
const { content, loading, loaded } = useSelector(state => ({
content: state.suply.content,
loading: state.suply.loading,
loaded: state.suply.loaded,
}))
const [items, setItems] = useState<Items[]>([])
const [category, setCategory] = useState<Category>(Category.emptyObject)
const [totalCountFromServer, setTotalCountFromServer] = useState<number>()
useEffect(() => {
if (content) {
setItems((content as RequestItems).items)
setCategory((content as RequestItems).category)
setTotalCountFromServer((content as RequestItems).totalCountFromServer)
}
}, [content])
或者这个这里我得到TypeError,因为选择器无法读取undefined的属性(阅读'items','category','totalCountFromServer')
const { content, loading, loaded } = useSelector(state => ({
items: (state.suply.content as RequestItems).items,
category: (state.suply.content as RequestItems).category,
totalCountFromServer: (state.suply.content as RequestItems).totalCountFromServer,
loading: state.suply.loading,
loaded: state.suply.loaded,
}))
或者像这样使用解构。它工作得很好,但我读到here,使用选择器的析构是错误的方法
const { content, loading, loaded } = useSelector(state => ({
content: state.suply.content,
loading: state.suply.loading,
loaded: state.suply.loaded,
}))
const {items, category, totalCountFromServer } = (content as RequestItems);
那么,有没有更好的方法来使用带有Union Type内容的状态,或者我最好使用我的原始结构?
1条答案
按热度按时间xyhw6mcr1#
遵循“定义类型化挂钩”文档。创建
useDispatch
和useSelector
钩子的类型化版本。使用歧视工会
例如
codesandbox