I have a custom hook that gets file data from the cache api based on an url. The hook works fine.
Problem is that I get a response back and I need to parse this data before I can use the fabric tag picker. and I also only want to parse that data when the user starts typing. I know that the prop "filterSuggestedTags" accepts a promise like call and we can fetch data before there.
You will see that I am using a fetch inside the filterSuggestedTags and that ensures to fetch the data from the url before showing the results, plus it shows the loader as well: https://codepen.io/deleite/pen/MWjBMjY?editors=1111
So given the code below and the fact that my useCache gives my a fetch response as state:
const filterSuggestedTags = async (filterText: string, tagList: ITag[]) => {
if (filterText) {
// how can I await the response state? before I can parse the data
return (await /* resp should be the state from the custom hook*/ resp.json()).map(item => ({ key: item.id, name: item.title }));
} else return []
};
This might save you some headaches with old sate, updates.
const useFilterSuggestedTags = async (filterText: string, tagList: ITag[]) => {
const [data, setData] = useState<WhateverYouReturn[]>([]);
useEffect(() => {
const controller = new AbortController();
if (filterText) fetchData();
async function fetchData() {
try {
const resp = await fetch('url', {signal: controller.signal});
const json = await resp.json();
if (!controller.signal.aborted) {
setData(json.map(_ => ({ key: _.id, name: _.title, })));
}
} catch(e) {
if (!(e instanceof AbortError)) throw e
}
}
// If your effect returns a function, React will run it when it is time to
// clean up:
return controller.abort;
}, [filterText, tagList])
return data;
};
How about
const useFilterSuggestedTags = async (filterText: string, tagList: ITag[]) => {
const [data, setData] = useState<WhateverYouReturn[]>([]);
if (filterText) fetchData();
return data;
async function fetchData() {
const resp = await {}; // Obviously fetch something
const json = await resp.json();
// I assume you also need to filter them, but I guess you know how
// to do that :P
setData(json.map(_ => ({ key: _.id, name: _.title, })));
}
};
Little notice: It is good practice to name your hooks use[...]
. At least that is what they (and the react-hooks es-lint plugin) suggest.