【发布时间】:2020-08-15 06:29:17
【问题描述】:
试图赶上React Hooks。我读到他们建议在处理复杂的state 时使用 Hook useReducer。但我的怀疑是从以下方案开始的:
使用 React + Typescript,假设我有一个包含多个字段的状态(我将举一个带有类的示例):
type Person = {
username: string,
email: string
}
type Pet = {
name: string,
age: number
}
this.state: MyState = {
person: Person,
pet: Pet,
loading: boolean
}
如果我想使用基于 Hooks 的新方法来处理这种状态,我可以考虑以下几种选择:
选项 1:为每个字段使用 Hook useState
const [person, setPerson] = useState<Person>(null)
const [pet, setPet] = useState<Pet>(null)
const [loading, setLoading] = useState<boolean>(false)
这种方法的缺点是可扩展性低,而且我的一些真实状态至少有15个字段,难以管理。
选项 2:对整个对象使用单个 setState
const [state, setState] = useState<MyState>({
person: null,
pet: null,
loading: false
})
这是对我来说似乎最简单的方法,我可以简单地执行setState((prev) => {...prev, person: {username: 'New', email: 'example@gmail.com'}}) 或使其适应任何字段修改。我什至可以一次更新多个字段。
选项 3: 为每个复杂字段使用 useReducer,为每个复杂字段传递一个特定的 reducer,为简单字段使用 useState
const [person, dispatchPerson] = useReducer<Person>(personReducer)
const [pet, dispatchPet] = useReducer<Pet>(petReducer)
const [loading, setLoading] = useState<boolean>(false)
我发现这个可以管理,但我看不出必须使用多行开关设置 reduce 函数的意义,除了在 Typescript 中为每个 reduce 函数设置调度类型的繁琐过程你可以只使用 setState 并完成它。
选项 4:为整个州使用一个 useReducer
const [state, dispatch] = useReducer(generalReducer)
主要问题是reducer的类型,想想15个字段,所有类型和更新它们的信息结构都不同。在 Typescript 中指定类型无法扩展或不清楚。有几篇关于此的文章,没有一篇以干净的方式解决问题 (example 1),或者它们非常简单,不适用于问题 (example 2)。
处理此类案件的最佳方法是什么?该州的字段数量很大并且可以具有多个深度级别。是否有代表这些案例的良好做法或任何官方示例?带有数字字段的示例用于处理博主或官方文档人员非常喜欢的简单计数器并不是很有帮助。
任何关于这个主题的观点都非常受欢迎!在此先感谢,对我的英语感到抱歉
【问题讨论】:
-
对于您想从应用程序中的任何位置
get/set的状态,Redux 策略对我来说似乎是合理的,您的选项 4,可选择使用选项 3。应用程序有一个带有一个减速器的大型状态树。您可以将责任分解为子减速器,最终使用combineReducers组合以创建总体减速器。对于本地组件状态,选项 1 和 2 对我来说很有意义。我倾向于使用选项 1。我同意你所说的一切。我还没有看到任何新的、创新的方式来使用useReducer。 -
这是一种解脱的读物,没有一种神奇的方式可以做我错过的事情。感谢您的评论!
-
我偶然发现了这个
useMethods减速器并想到了你。这是一种有趣的搭建东西的方式。 -
酷!非常感谢!
标签: reactjs typescript react-hooks