我可以在解析数据之前等待一个状态吗?
can I await for a state before parsing the data in react?
我有一个自定义挂钩,可以根据 url 从缓存 api 中获取文件数据。钩子很好用。
问题是我收到了回复,我需要解析这些数据才能使用结构标签选择器。而且我也只想在用户开始输入时解析该数据。
我知道道具“filterSuggestedTags”接受类似调用的承诺,我们可以在那之前获取数据。
你会看到我在 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 []
};
请注意,这未经测试,我也不认为这是最好的做法,只是一些想法。
编辑:经过一番思考,这可能更好
这可能会让您在处理旧状态和更新时头疼不已。
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, 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, })));
}
};
注意事项:给你的钩子命名是个好习惯use[...]
。至少他们(以及 react-hooks es-lint 插件)是这么建议的。
我有一个自定义挂钩,可以根据 url 从缓存 api 中获取文件数据。钩子很好用。
问题是我收到了回复,我需要解析这些数据才能使用结构标签选择器。而且我也只想在用户开始输入时解析该数据。 我知道道具“filterSuggestedTags”接受类似调用的承诺,我们可以在那之前获取数据。
你会看到我在 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 []
};
请注意,这未经测试,我也不认为这是最好的做法,只是一些想法。
编辑:经过一番思考,这可能更好
这可能会让您在处理旧状态和更新时头疼不已。
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, 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, })));
}
};
注意事项:给你的钩子命名是个好习惯use[...]
。至少他们(以及 react-hooks es-lint 插件)是这么建议的。