我开始尝试使用xstate,并决定从创建一个fetch机器开始,它将负责处理我向服务器发出的每个请求。
我创建了一个简单的状态机:
import { createMachine, assign } from "xstate";
interface FetchContext {
readonly results: any | null;
readonly error: null | string;
}
type FetchServices = {
readonly fetchData: {
readonly data: any;
};
}
export const fetchMachine = createMachine(
{
context: {
results: null,
error: null,
},
tsTypes: {} as import("./fetch.typegen").Typegen0,
schema: {
context: {} as FetchContext,
services: {} as FetchServices,
},
id: "fetch",
initial: "idle",
states: {
idle: {
on: {
FETCH: {
target: "pending",
},
},
},
pending: {
invoke: {
src: "fetchData",
onDone: { target: "success", actions: "setResults" },
onError: { target: "failed", actions: "setError" },
},
},
success: {
on: {
FETCH: {
target: "pending",
},
},
},
failed: {
on: {
FETCH: {
target: "pending",
},
},
},
},
},
{
actions: {
setResults: assign((context, event) => {
return {
results: event.data,
error: null,
};
}),
setError: assign((context, event) => {
return {
results: null,
error: event.data as string,
};
}),
},
}
);
这里的主要问题是我想让这个fetchMachine负责具有不同返回类型的不同请求。正如你所看到的,在我的代码中获取的数据类型是“any”,我想修正这个问题。如果我只对一个请求使用fetchMachine,我会描述返回的对象类型,这样问题就不会出现了,但是在我的例子中,我想让这个fetchMachine重用于许多不同的服务。
第二个问题(与服务无关)是,如果我从“setError”操作的返回属性“error”中删除“as string”,typescript将报告“event.data“是未知类型,无法分配给“string| null”,正如我在FetchContext接口中描述的错误类型。在这种情况下,是否有方法正确地键入错误?
另外,在状态机中为每个“get”请求使用一个单独的抓取机是一个好的实践吗?我的意思是,有时候我曾经创建一个useFetch钩子来处理大多数请求,这就是我问这个问题的原因。
1条答案
按热度按时间8e2ybdfx1#
关于主要问题,我会使用接受泛型的工厂函数:
关于第二个问题,您可以阅读更多关于here的内容,当使用
typegen
时,应该像示例中那样强制转换错误类型。至于通用的fetch机器,这是我开始使用xState时做的第一件事,但随着时间的推移,我发现简单的
invoke promises
对我来说工作得更好、更干净。