【发布时间】:2022-01-20 07:55:32
【问题描述】:
我们制作了一个自定义挂钩来为我们获取数据。获取部分被我们生成的获取 API 替换,我们作为参数传递下来。
interface RequestModel<T> {
loading: boolean;
error: string | null;
data: T | null;
}
export default function useRequest<T>(url: string): [boolean, string | null, T | null, Dispatch<SetStateAction<RequestModel<T>>>] {
const [data, setData] = useState<RequestModel<T>>({
loading: false,
error: null,
data: null
});
useEffect(() => {
setData({
loading: true,
error: null,
data: null
});
fetch(url)
.then((response) => response.json())
.then((json) =>
setData({
loading: false,
error: null,
data: json
})
)
.catch((error) => {
setData({
loading: false,
error: error.message,
data: null
});
});
}, [url]);
return [data.loading, data.error, data.data, setData];
}
它的用法是这样的:
const [loading, error, data, setData] = useRequest<Todo>(url);
现在当我们调用 setData 时出现的问题是 prevState 可能是null(例如请求失败并且从未设置数据)。所以像这样调用 setData 会导致错误:
function handleChange(event: ChangeEvent<HTMLInputElement>) {
setData((prevState) => ({
...prevState,
data: {
...prevState.data,
[event.target.name]: event.target.title
}
}));
}
将使用 prevState 的 setData 包装在 if (data) {} 中不起作用。我想这是因为 setState 是异步的,并且在调用 setData 时数据可能会更改为 null(因此它的属性未定义)。
问题 1 关于如何使这个 useRequest 挂钩起作用的任何建议?理想情况下,我希望能够使用数据,而不必在每次使用时都检查 null 或 undefined(对于上述情况,这是不可能的)。
问题 2
我还认为可以使用默认状态初始化数据并使用默认状态而不是将数据设置为null。有没有办法根据 Typescript 中的接口/类型生成默认对象?类似于 Java,其中变量具有默认值。
【问题讨论】:
标签: reactjs typescript types