在 TypeScript 中将函数传递给反应路由器操作?

问题描述 投票:0回答:1

我正在尝试使用 Auth0 的

useAuth0()
钩子在 React-router 操作中检索
getAccessTokenSilently()
,这样我就可以获得访问令牌来对我的服务进行受保护的 API 调用来执行该操作。

基于过去的类似问题,执行此操作的方法似乎是调用父应用程序组件中的挂钩,然后将其作为函数传递给任何需要它的加载器或操作。酷,听起来很棒!

不幸的是 TypeScript 完全拒绝允许这样做。

我尝试创建一个扩展 ActionFunctionArgs 的自定义类型,以便 TypeScript 知道会有另一个属性,但这只会导致有关我的操作函数无法分配给路由的 action: 属性的错误。

有人曾经成功地做到过吗?如何在 TypeScript 的操作中使用身份验证挂钩?还有其他方法可以做到这一点吗?

编辑:这是代码。

main.tsx:

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

appAction.mts(我想在其中使用身份验证内容的操作):

import { ActionFunction } from "react-router-dom";

export const appAction: ActionFunction =
  ({ getAccessTokenSilently }) =>
  async ({ request, params }) => {
    const token = await getAccessTokenSilently();
    const formData = await request.formData();
    const intent = formData.get("intent");

    // Do something with the token here when calling an API.
  };

App.tsx:

const App: React.FC = () => {
  const { getAccessTokenSilently } = useAuth0();
  const router = createBrowserRouter([
    {
      element: <Auth0ProviderLayout />,
      errorElement: <ErrorPage />,
      children: [    
        {
          path: "/verifier",
          element: <ProtectedRoute component={Verifier} />,
          loader: activeFlightPlansLoader,
          action: appAction({ getAccessTokenSilently }),
... etc

Typescript 在这方面有很多问题。

  • 对于
    appAction
    函数定义,它说:

“类型‘ActionFunctionArgs’上不存在属性‘getAccessTokenSilently’”

  • 对于在创建路线时将
    appAction
    分配给
    action
    属性,它说:

输入“数据函数值 |承诺’不是
可分配给类型“ActionFunction |不明确的'。类型“null”不是
可分配给类型“ActionFunction |未定义'

和:

类型参数 '{ getAccessTokenSilently: { (选项: GetTokenSilentlyOptions & { 详细响应:true; }): 承诺; (选项?: 静默获取令牌选项 |未定义):承诺<...>; (选项: GetTokenSilentlyOptions): Promise<...>; }; }' 不可分配给 “ActionFunctionArgs”类型的参数。对象字面量只能 指定已知属性,并且“getAccessTokenSilently”不存在 在“ActionFunctionArgs”类型中。

typescript react-router auth0
1个回答
1
投票

函数

appAction
不是
ActionFunction
类型,而是一个返回该类型的动作函数。

import type { ActionFunction } from "react-router-dom";

interface AppAction {
  getAccessTokenSilently: () => Promise<string>; // <-- or whatever this needs to be
}

const appAction = ({
  getAccessTokenSilently
}: AppAction): ActionFunction => async ({ request, params }) => {
  const token = await getAccessTokenSilently();
  const formData = await request.formData();
  const intent = formData.get("intent");

  // Do something with the token here when calling an API.
};
© www.soinside.com 2019 - 2024. All rights reserved.