在React中编写箭头函数异步获取数据

huangapple go评论105阅读模式
英文:

Typing arrow async fetch functions in react

问题

我正在尝试编写一个箭头函数来获取一个 JSON 文件。问题是 JSON 返回给我一个对象中包含对象的结构。

我试图使它不必描述每个对象(因为可能存在多层嵌套),而是通过类型来实现:

type Dictionary = {
  menu: Record<string, unknown>;
  pages: Record<string, unknown>;
  result: Record<string, unknown>;
};

我的函数如下:

const getData = async (lang: string): Promise<Dictionary> => {
  const path = `src/assets/file${lang}.json`;
  try {
    const response = await fetch(path);
    if (!response.ok) {
      throw new Error(`Some error`);
    }
    const data = await response.json();
    setDict(data.menu);
  } catch (error) {
    if (error) setError(error);
  }
};
useEffect(() => {
  getData(lang);
}, []);

但我得到了以下错误:

  • any 值的不安全赋值。
  • 对类型为 any 的不安全参数进行分配给类型为 SetStateAction<null> 的参数。
  • any 值上进行不安全的成员访问.menu
  • 类型为 '{}' 的参数不能分配给类型为 'SetStateAction<null>' 的参数。
  • 类型 '{}' 与签名 '(prevState: null):null' 不匹配。

从哪里开始修复它?我错过了什么?

英文:

I'm trying to type an arrow function that gets a json file. The problem is that json returns me an object of objects.

I'm trying to make it so that I don't have to describe each object (because there may be several levels of nesting) and do it through the type:

  type Dictionary = {
    menu: Record&lt;string, unknown&gt;;
    pages: Record&lt;string, unknown&gt;;
    result: Record&lt;string, unknown&gt;;
  };

My function:

  const getData = async (lang: string): Promise&lt;Dictionary&gt; =&gt; {
    const path = `src/assets/file${lang}.json`;
    try {
      const response = await fetch(path);
      if (!response.ok) {
        throw new Error(`Some error`);
      }
      const data = await response.json();
      setDict(data.menu);
    } catch (error) {
      if (error) setError(error);
    }
  };
  useEffect(() =&gt; {
    getData(lang);
  }, []);

But I get errors:
Unsafe assignment of an any value.

Unsafe argument of type any assigned to a parameter of type SetStateAction&lt;null&gt;

Unsafe member access .menu on an any value.

Argument of type '{}' is not assignable to parameter of type 'SetStateAction<null>'.

Type '{}' provides no match for the signature '(prevState: null): null'.

Where to start to fix it? What did I missed?

答案1

得分: 1

不要使用 getData 函数来直接设置状态,而是可以让它返回具有显式类型注释的数据。类似这样:

const getData = async (lang: string): Promise<Dictionary> => {
  try {
    ... 所有逻辑
    const data = await response.json();
    return {
      menu: data.menu as Record<string, unknown>,
      pages: data.pages as Record<string, unknown>,
      result: data.result as Record<string, unknown>,
    };
  } catch (error) {
    ... 错误处理
  }
}

然后从 useEffect 中设置状态,像这样:

useEffect(() => {
  getData(lang)
    .then((data) => {
      setDict(data.menu);
    })
    .catch((error) => {
      ..处理错误
    })
}, [])

或者如果你喜欢的话,你也可以从函数中设置它,通过在调用 setter 之前首先使用正确类型的类型注释创建对象。在这种情况下,你可能需要将 getData 函数的返回类型更改为 void,我想你可以选择任何一种方式。

英文:

instead of getData function to set the state directly you can get it to return the data with explicit type annotations. something like this,

const getData = async (lang: string): Promise&lt;Dictionary&gt; =&gt; {
  try {
    ... all logics
    const data = await response.json();
    return {
      menu: data.menu as Record&lt;string, unknown&gt;,
      pages: data.pages as Record&lt;string, unknown&gt;,
      result: data.result as Record&lt;string, unknown&gt;,
    };
  } catch (error) {
    ... error handling
  }
}

then set the state from useEffect. like this,

useEffect(() =&gt; {
  getData(lang)
    .then((data) =&gt; {
      setDict(data.menu);
    })
    .catch((error) =&gt; {
      ..handle error
    })
}, [])

Or you can set it from the function if your prefer by creating the object first with correct type type annotations before calling the setter. In that case you will need to change the return type of your getData function to void i think. which ever you prefer.

huangapple
  • 本文由 发表于 2023年7月13日 18:58:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76678605.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定