'React custom utility function seeing Uncaught TypeError: Invalid attempt to destructure non-iterable instance
I have the following code in my React App component, where I am trying to get some JSON and want to send that to my custom hook.
const fetchFn = useCommonFetch();
const [user1, status1] = fetchFn('myapi/urls', {}, 'GET');
useEffect(() => {
someCustomHookCall(user1); // Pass "user1" JSON info to someCustomHookCall
}, [user1])
Below is how the useCommonFetch looks;
import {useEffect, useState} from 'react';
export default function useCommonFetch() {
const fetchData = async (url, reqData, requestType) => {
try {
var statusObj = {
statMsg: null,
errMsg: null,
status: null,
};
var reqOptions = {
credentials: 'same-origin'
}
if (requestType === 'POST') {
reqOptions.headers = {};
reqOptions.headers['Accept'] = 'application/json';
reqOptions.method = 'POST';
reqOptions.body = JSON.stringify(reqData);
}
const response = await fetch(url, reqOptions);
if (!response.ok) {
throw response;
}
statusObj.status = "success";
const json = await response.json();
return [json, statusObj];
} catch (error) {
statusObj.status = "error";
if (error && error.status) {
switch (error.status) {
case 401:
statusObj.errMsg = "Unauthorized";
console.error("Unauthorized: " + error.status);
break;
default:
statusObj.errMsg = "Sys error";
}
}
return [null, statusObj];
}
}
return fetchData;
}
I am getting the following error while running
Uncaught TypeError: Invalid attempt to destructure non-iterable instance.
In order to be iterable, non-array objects must have a Symbol.iterator method.
Not sure what is wrong in the calling code.
Solution 1:[1]
The error occurs because you're trying to destructure a pending promise.
I have created a short codesandbox that suggests another way of achieving your expectation, but something causes the component to re-render nonstop.
Solution 2:[2]
fetchFn is an asynchronous function and it returns a promise(and not an array), I suggest you change the useCommonFetch as follows:
import {useEffect, useState} from 'react';
const fetchData = async (url, reqData, requestType) => {
...
}
export default function useCommonFetch(url, reqData, requestType) {
const [state, setState] = useState([null, null]);
useEffect(() => {
async function getData() {
const result = await fetchData(url, reqData, requestType);
setState(result);
}
getData();
}, [url, reqData, requestType])
return state;
}
You can use it like this:
const [user1, status1] = useCommonFetch('myapi/urls', null, 'GET');
useEffect(() => {
if(user1) {
someCustomHookCall(user1); // Pass "user1" JSON info to someCustomHookCall
}
}, [user1])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Art |
| Solution 2 |
