You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React集成CASL实现ACL时出现t.on is not a function错误如何解决

报错根因与修复方案

你遇到的报错t.on is not a function本质是Can组件获取到的Ability实例不符合预期,不存在CASL内置的事件监听on方法,可按以下步骤排查修复:

  • 检查Ability类导入是否正确
    你需要确保在App.tsx中是从@casl/ability包导入的Ability构造函数,错误的导入路径、导入其他同名类都会导致初始化的实例缺少内置方法:
import { Ability } from '@casl/ability';
  • 修复异步权限请求的加载逻辑
    你通过接口异步获取权限数据,在接口返回前caslAbilities大概率为undefined或空值,直接传给AbilityContext.Provider会导致Can组件拿到无效实例。可以增加加载态判断,在权限实例初始化完成后再渲染子组件:
import { useState, useEffect } from 'react';
import { Ability } from '@casl/ability';
import { AbilityContext } from './Auth/can';

function App() {
  const [caslAbilities, setCaslAbilities] = useState<Ability | null>(null);

  useEffect(() => {
    // 你的接口请求逻辑
    getAbilityJsonFromApi().then(abilitiesJson => {
      setCaslAbilities(new Ability(abilitiesJson))
    })
  }, [])

  // 权限初始化完成前返回加载态,避免传递无效值
  if (!caslAbilities) return <div>加载中...</div>

  return (
    <AbilityContext.Provider value={caslAbilities}>
      <Main />
    </AbilityContext.Provider>
  )
}
  • (可选)关闭Can组件的订阅逻辑
    如果你的业务不需要动态变更权限,可在创建Can组件时关闭事件监听,避免调用on方法:
// can.js
import { createContext } from 'react';
import { createContextualCan } from '@casl/react';

export const AbilityContext = createContext();
// 增加subscribe: false配置关闭事件订阅
export const Can = createContextualCan(AbilityContext.Consumer, { subscribe: false });
  • (可选)适配React Router v6的路由结构
    如果你使用的是React Router v6,Route组件只能作为Routes的直接子组件,直接用Can包裹Route会触发路由结构错误,建议将权限判断放到element内部:
<Route 
  path="/reporting" 
  element={
    <Can I="read" a="Post">
      <ReportingHome />
    </Can>
  }
/>

内容的提问来源于stack exchange,提问作者user101289

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:36:03