admin管理员组

文章数量:1293989

I am getting the following error:

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

My relevant code looks like this:

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);
};

Obviously data is not being initialized with the data returned from the getEvents function. What I cannot figure out is why? I am using TypeScript and so far no errors are being thrown from the getEvents function.

I am new to React and TypeScript so I might be missing something and so far all the similar questions I have seen online do not seem to be relevant to my error.

I am getting the following error:

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

My relevant code looks like this:

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);
};

Obviously data is not being initialized with the data returned from the getEvents function. What I cannot figure out is why? I am using TypeScript and so far no errors are being thrown from the getEvents function.

I am new to React and TypeScript so I might be missing something and so far all the similar questions I have seen online do not seem to be relevant to my error.

Share asked Jun 30, 2021 at 3:26 cp-stackcp-stack 8763 gold badges19 silver badges46 bronze badges 1
  • Yes. That’s the line that’s throwing the error – cp-stack Commented Jun 30, 2021 at 3:58
Add a ment  | 

2 Answers 2

Reset to default 5

First of all let's look at SetStateAction<never[]>. If you hover over serverData in this line:

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

It will tell you the type of serverData is never[]. The problem is that [] is not enough information for typescript to know what should into that array, since there is no contents to infer types from. To do that you need to pass in a type parameter to useState.

I dont know the shape of your data, but something like:

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

Now if you hover over serverData you should see:

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

And if you hover over serverDataLoaded you should see:

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

So now that function is a React set state action that takes the type you defined.


Now let's look at the other side of your problem: Why is that value you're trying to assign void?.

If you hover over getEvents, you should see the inferred return type of that function. You should see this:

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

So typescript believes that the function returns a promise, that resolve to void. That means that typescript didn't see a return statement in your function.

Why is that? Well, the only return statement is in a nested function. You seem to have mixed up async/await and the promise based .then() style. You should never use both of these. In this case you only need to await the call to the api, and then use whatever it returned:

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

Now that return statement is hit in the normal function flow, and now in a nested function.

See: How to return a result properly from async/await function? for more information on this.


Now, after all that, getEvents returns a value instead of void, and serverData and serverDataLoaded both have the right types, and it should work as you expect.

See typescript playground

Debug your execution of getEvents function where you have mixed up both async await and .then handling of promise

本文标签: