1

我有一个自定义挂钩,可以根据 url 从缓存 api 获取文件数据。钩子工作正常。

问题是我得到了回复,我需要先解析这些数据,然后才能使用结构标签选择器。而且我也只想在用户开始输入时解析该数据。我知道道具“filterSuggestedTags”接受像 call 这样的承诺,我们可以在此之前获取数据。

您会看到我在 filterSuggestedTags 中使用了 fetch,并确保在显示结果之前从 url 中获取数据,此外它还显示了加载器: https ://codepen.io/deleite/pen/MWjBMjY?editors =1111

因此,鉴于下面的代码以及我的 useCache 将我的 fetch 响应作为状态的事实:

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 []
  };
4

1 回答 1

0

请注意,这没有经过测试,我也不认为这是最好的做法,只是一些想法。

编辑:经过一番思考,这可能会更好

这可能会为您节省一些旧状态更新的麻烦。

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 插件)所建议的。

于 2021-01-14T08:18:31.423 回答