【问题标题】:Argument of type 'void' is not assignable to parameter of type 'SetStateAction<never[]>'“void”类型的参数不能分配给“SetStateAction<never[]>”类型的参数
【发布时间】:2021-06-30 03:26:53
【问题描述】:

我收到以下错误:

Argument of type 'void' is not assignable to parameter of type 'SetStateAction<never[]>'.

我的相关代码如下所示:

const ViewEvents: React.FC<ViewEventsProps> = ({ navigation }) => {

const flatListRef = useRef(null);
const [limit] = useState(5);
const [page, setPage] = useState(1);
const [clientData, setClientData] = useState([]);
const [serverData, serverDataLoaded] = useState([]);
const [pending_process, setPending_process] = useState(true);
const [loadmore, setLoadmore] = useState(false);
const [refresh, setRefresh] = useState(false);

const getEvents = async (thePage: any) => {
    try {
        const value = await AsyncStorage.getItem('user_id');
        if (value !== null) {
            // We have data!!
            const user_id = JSON.parse(value)
            const response = await APIKit.get('/v1/events/user-events/' + user_id)
                .then((response) => {
                    console.log(response.data)
                    return response.data.slice((thePage - 1) * limit, thePage * limit);
                }, (error) => {
                    console.log(error);
                });
        }
    } catch (error) {
        // Error retrieving data
    }
}

const requestToServer = async (thePage: any) => {
    let data = await getEvents(thePage);
    console.log('data', data);
    serverDataLoaded(data);
};

显然数据没有被 getEvents 函数返回的数据初始化。我无法弄清楚为什么?我正在使用 TypeScript,到目前为止 getEvents 函数没有抛出任何错误。

我是 React 和 TypeScript 的新手,所以我可能会遗漏一些东西,到目前为止,我在网上看到的所有类似问题似乎都与我的错误无关。

【问题讨论】:

  • 是的。这就是引发错误的那一行

标签: javascript typescript react-native


【解决方案1】:

首先让我们看看SetStateAction&lt;never[]&gt;。如果您将鼠标悬停在此行中的 serverData 上:

const [serverData, serverDataLoaded] = useState([]);

它会告诉你serverData 的类型是never[]。问题是[] 没有足够的信息让打字稿知道该数组应该包含什么,因为没有内容可以从中推断类型。为此,您需要将类型参数传递给useState

我不知道您的数据的形状,但类似于:

const [serverData, serverDataLoaded] =
  useState<{ id: number, name: string }[]>([]);

现在,如果您将鼠标悬停在 serverData 上,您应该会看到:

const serverData: {
    id: number;
    name: string;
}[]

如果您将鼠标悬停在 serverDataLoaded 上,您应该会看到:

const serverDataLoaded: React.Dispatch<React.SetStateAction<{
    id: number;
    name: string;
}[]>>

所以现在这个函数是一个 React 设置状态动作,它采用你定义的类型。


现在让我们看看问题的另一面:为什么您要分配的值是void?。

如果您将鼠标悬停在 getEvents 上,您应该会看到该函数的推断返回类型。你应该看到这个:

const getEvents: (thePage: any) => Promise<void>

所以 typescript 认为该函数返回一个承诺,即解析为 void。这意味着 typescript 在您的函数中没有看到 return 语句。

这是为什么呢?好吧,唯一的 return 语句是在嵌套函数中。您似乎混淆了async/await 和基于.then() 的承诺风格。你不应该同时使用both。在这种情况下,您只需 await 调用 api,然后使用它返回的任何内容:

const response = await APIKit.get('/v1/events/user-events/' + user_id)
console.log(response.data)
return response.data.slice((thePage - 1) * limit, thePage * limit);

现在return 语句在正常函数流中被命中,现在在嵌套函数中。

有关更多信息,请参阅:How to return a result properly from async/await function?


现在,毕竟getEvents 返回一个值而不是void,并且serverDataserverDataLoaded 都具有正确的类型,它应该可以按预期工作。

See typescript playground

【讨论】:

  • 非常感谢您的详细解释。我能够根据您提供的建议解决问题。我将返回文档以更好地了解 useState 功能,因为我认为这是我最大的误解。
【解决方案2】:

调试您对getEvents 函数的执行,其中您混淆了async await.then 处理promise

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 2021-12-04
    • 2021-08-01
    • 2018-11-03
    • 2021-06-09
    • 2021-05-16
    • 2021-12-04
    • 2021-10-23
    相关资源
    最近更新 更多