问题描述
我有一个自定义钩子,可以根据 url 从缓存 api 中获取文件数据。挂钩工作正常。
问题是我收到了回复,我需要先解析这些数据,然后才能使用 Fabric 标签选择器。而且我也只想在用户开始输入时解析该数据。 我知道道具“filterSuggestedTags”接受像 call 这样的承诺,我们可以在那里获取数据。
您会看到我在 filterSuggestedTags 中使用了 fetch 并确保在显示结果之前从 url 中获取数据,此外它还显示了加载程序: https://codepen.io/deleite/pen/MWjBMjY?editors=1111
鉴于下面的代码以及我的 useCache 将获取响应作为状态这一事实:
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 []
};
解决方法
请注意,这未经测试,我也不认为这是最好的做法,只是一些想法。
编辑:经过一些思考,这可能会更好
这可能会为您省去旧状态、更新的麻烦。
class GetData(APIView):
def get(self,request,*args,**kwargs):
urls = [url_1,url_2,url_3,url_4
]
data_bundle = []
for x in urls:
response = requests.get(x,headers={'Content-Type': 'application/json'}).json()
data_bundle.append(response)
return Response(data_bundle,status=status.HTTP_200_OK)
旧答案
怎么样
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;
};
小提示:将钩子命名为 const useFilterSuggestedTags = async (filterText: string,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,})));
}
};
是一个好习惯。至少这是他们(以及 react-hooks es-lint 插件)建议的。