I'm trying to return a function (closure) from a async function. So far, the way I have things space is always a promise and not a function, even though it should be a closure.
// ...
const [space, set_space] = React.useState(false);
React.useEffect(
() => {
API.SERVER(query, PAGE_SIZE)
.then(response => set_space(response));
},
[query]
);
React.useEffect(
() => {
console.log(space.constructor);
if (space) {
space(page)
.then(response => set_titles(Array.from(response.data)));
}
},
[space, page]
);
// ...
API
// ...
export default {
SERVER:async function(search, width)
{
if (!search) {
// return () => {};
search = DEFAULT_QUERY;
}
const all = (await axios.get(SEARCH_URL `?search=${search}`)).data;
console.log(all);
const pages = chunk(all, width);
// function pager(results) {
// const dex = (results > width ? results / width : 0);
// const next = pages[dex];
// return axios.get(SEARCH_URL `?fromids=${next}`);
// }
// return pager;
return function(results) {
const dex = (results > width ? results / width : 0);
const next = pages[dex];
return axios.get(SEARCH_URL `?fromids=${next}`);
};
// return pager;
}
};
space.constructor says it's a Promise, but it should be a function that returns axios' Promise, not a Promise it's self. I can't really change the way the API is set up because I need to hold the index client side, then walk though it by changing space's parameter.
CodePudding user response:
The problem is, that set_space doesn't handle functions the same way as other values.
That's because React's state setters can take a callback that receives the previous state as an argument.
However, React has no way of differentiating between a callback and a value that happens to be a function. So, React will assume it's a callback and calls it, then set the state to contain its return value, another Promise.
To put the function itself into the state, you can create a callback that returns the function, like this:
API.SERVER(query, PAGE_SIZE)
.then(response => set_space(() => response));
CodePudding user response:
Hmmm... you just want a function that on call returns you the promise? What about useCallback then?
const triggerAsync = React.useCallback(
() => {
return API.SERVER(query, PAGE_SIZE)
.then(response => set_space(response))
},
[query]
);
triggerAsync should then return a promise when you execute it
