为 useLoaderData() 声明什么类型,在哪里?

Zon*_*org 7 typescript reactjs react-router-dom

我正在研究 NetNin​​jareact-router深入 #6 教程,但我正在尝试使用打字稿来完成它。我正在从 JSON 对象获取数据,并使用钩子useLoaderData()并尝试映射 JSON 对象。我只是不确定在哪里声明类型和/或声明哪种类型。这是我的组件:

import { NavLink, Link, Outlet, useLoaderData } from 'react-router-dom'

type Token = {
  id: number
  name: string
  ticker: string
  description: string
}

const Tokens = () => { 
  const tokens = useLoaderData()

  return ( 
    <div>
      <div>
        {tokens.map((token: Token) => (
          <Link to='/' key={token.id}>
            <p>{token.name}</p>
            <p>{token.ticker}</p>
            <p>{token.description}</p>
          </Link>
        ))}
      </div>
      <nav>
        <NavLink to='uniswap'>Uniswap</NavLink>
        <NavLink to='balancer'>Balancer</NavLink>
      </nav>
      <Outlet />
    </div>
  );
}

//loader function
export const tokensLoader = async () => {
  const res = await fetch('http://localhost:4000/tokens')

  return res.json()
}
 
export default Tokens;
Run Code Online (Sandbox Code Playgroud)

JSON 对象:

{
  "tokens": [
    {
      "id": 1,
      "name": "uniswap",
      "ticker": "UNI",
      "description": "This is the description for Uniswap token"
    },
    {
      "id": 2,
      "name": "balancer",
      "ticker": "BAL",
      "description": "This is the description for Balancer token"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我的直觉感觉应该是这样的:

const tokens: Token[] = useLoaderData()
Run Code Online (Sandbox Code Playgroud)

或者

type TokenData = {
  tokens: Token[]
}

const tokens: TokenData = useLoaderData()
Run Code Online (Sandbox Code Playgroud)

仅仅按照本教程,发生了很多事情,超出了我目前的理解。我应该声明哪种类型以及在哪里?

Dre*_*ese 5

钩子的返回类型useLoaderDataunknown

查看来源

export function useLoaderData(): unknown {
  let state = useDataRouterState(DataRouterStateHook.UseLoaderData);
  let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);

  if (state.errors && state.errors[routeId] != null) {
    console.error(
      `You cannot \`useLoaderData\` in an errorElement (routeId: ${routeId})`
    );
    return undefined;
  }
  return state.loaderData[routeId];
}
Run Code Online (Sandbox Code Playgroud)

只需将返回类型转换为您的TokenData类型即可。不要忘记解构tokens您想要映射到 JSX 的数组。

export function useLoaderData(): unknown {
  let state = useDataRouterState(DataRouterStateHook.UseLoaderData);
  let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);

  if (state.errors && state.errors[routeId] != null) {
    console.error(
      `You cannot \`useLoaderData\` in an errorElement (routeId: ${routeId})`
    );
    return undefined;
  }
  return state.loaderData[routeId];
}
Run Code Online (Sandbox Code Playgroud)
export type Token = {
  id: number;
  name: string;
  ticker: string;
  description: string;
};

export type TokenData = {
  tokens: Token[];
};
Run Code Online (Sandbox Code Playgroud)

完整示例:

const { tokens } = useLoaderData() as TokenData;
Run Code Online (Sandbox Code Playgroud)

编辑声明类型供使用loaderdata-which-type-to-declare-and-where