“void”类型的参数不可分配给“SetStateAction<never[]>”类型的参数

sta*_*flo 1 javascript typescript react-native

我收到以下错误:

Argument of type 'void' is not assignable to parameter of type 'SetStateAction<never[]>'.
Run Code Online (Sandbox Code Playgroud)

我的相关代码如下所示:

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);
};
Run Code Online (Sandbox Code Playgroud)

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

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

Ale*_*yne 5

首先我们来看看SetStateAction<never[]>。如果您将鼠标悬停serverData在这一行上:

const [serverData, serverDataLoaded] = useState([]);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

const serverData: {
    id: number;
    name: string;
}[]
Run Code Online (Sandbox Code Playgroud)

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

const serverDataLoaded: React.Dispatch<React.SetStateAction<{
    id: number;
    name: string;
}[]>>
Run Code Online (Sandbox Code Playgroud)

现在该函数是一个 React 设置状态操作,它采用您定义的类型。


现在让我们看看问题的另一面:为什么你要分配这个值void

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

const getEvents: (thePage: any) => Promise<void>
Run Code Online (Sandbox Code Playgroud)

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

这是为什么?嗯,唯一的 return 语句是在嵌套函数中。你似乎混淆了async/await基于承诺的.then()风格。你永远不应该同时使用这两个。在这种情况下,您只需要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);
Run Code Online (Sandbox Code Playgroud)

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

请参阅:如何从 async/await 函数正确返回结果?欲了解更多信息。


现在,毕竟,getEvents返回一个值而不是void,并且serverData两者serverDataLoaded都有正确的类型,并且它应该按您的预期工作。

查看打字稿游乐场