英文:
Typing arrow async fetch functions in react
问题
我正在尝试编写一个箭头函数来获取一个 JSON 文件。问题是 JSON 返回给我一个对象中包含对象的结构。
我试图使它不必描述每个对象(因为可能存在多层嵌套),而是通过类型来实现:
type Dictionary = {
menu: Record<string, unknown>;
pages: Record<string, unknown>;
result: Record<string, unknown>;
};
我的函数如下:
const getData = async (lang: string): Promise<Dictionary> => {
const path = `src/assets/file${lang}.json`;
try {
const response = await fetch(path);
if (!response.ok) {
throw new Error(`Some error`);
}
const data = await response.json();
setDict(data.menu);
} catch (error) {
if (error) setError(error);
}
};
useEffect(() => {
getData(lang);
}, []);
但我得到了以下错误:
- 对
any
值的不安全赋值。 - 对类型为
any
的不安全参数进行分配给类型为SetStateAction<null>
的参数。 - 在
any
值上进行不安全的成员访问.menu
。 - 类型为
'{}'
的参数不能分配给类型为'SetStateAction<null>'
的参数。 - 类型
'{}'
与签名'(prevState: null):null'
不匹配。
从哪里开始修复它?我错过了什么?
英文:
I'm trying to type an arrow function that gets a json file. The problem is that json returns me an object of objects.
I'm trying to make it so that I don't have to describe each object (because there may be several levels of nesting) and do it through the type:
type Dictionary = {
menu: Record<string, unknown>;
pages: Record<string, unknown>;
result: Record<string, unknown>;
};
My function:
const getData = async (lang: string): Promise<Dictionary> => {
const path = `src/assets/file${lang}.json`;
try {
const response = await fetch(path);
if (!response.ok) {
throw new Error(`Some error`);
}
const data = await response.json();
setDict(data.menu);
} catch (error) {
if (error) setError(error);
}
};
useEffect(() => {
getData(lang);
}, []);
But I get errors:
Unsafe assignment of an any
value.
Unsafe argument of type any
assigned to a parameter of type SetStateAction<null>
Unsafe member access .menu on an any
value.
Argument of type '{}' is not assignable to parameter of type 'SetStateAction<null>'.
Type '{}' provides no match for the signature '(prevState: null): null'.
Where to start to fix it? What did I missed?
答案1
得分: 1
不要使用 getData
函数来直接设置状态,而是可以让它返回具有显式类型注释的数据。类似这样:
const getData = async (lang: string): Promise<Dictionary> => {
try {
... 所有逻辑
const data = await response.json();
return {
menu: data.menu as Record<string, unknown>,
pages: data.pages as Record<string, unknown>,
result: data.result as Record<string, unknown>,
};
} catch (error) {
... 错误处理
}
}
然后从 useEffect
中设置状态,像这样:
useEffect(() => {
getData(lang)
.then((data) => {
setDict(data.menu);
})
.catch((error) => {
..处理错误
})
}, [])
或者如果你喜欢的话,你也可以从函数中设置它,通过在调用 setter 之前首先使用正确类型的类型注释创建对象。在这种情况下,你可能需要将 getData
函数的返回类型更改为 void
,我想你可以选择任何一种方式。
英文:
instead of getData function to set the state directly you can get it to return the data with explicit type annotations. something like this,
const getData = async (lang: string): Promise<Dictionary> => {
try {
... all logics
const data = await response.json();
return {
menu: data.menu as Record<string, unknown>,
pages: data.pages as Record<string, unknown>,
result: data.result as Record<string, unknown>,
};
} catch (error) {
... error handling
}
}
then set the state from useEffect. like this,
useEffect(() => {
getData(lang)
.then((data) => {
setDict(data.menu);
})
.catch((error) => {
..handle error
})
}, [])
Or you can set it from the function if your prefer by creating the object first with correct type type annotations before calling the setter. In that case you will need to change the return type of your getData function to void i think. which ever you prefer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论