React+TS中使用useMemo包裹选项数组出现类型报错如何解决
问题根因
核心错误是useMemo的回调函数中多写了一对方括号,导致回调最终返回的是二维数组BottomSheetAction[][],和你声明的一维数组类型BottomSheetAction[]完全不匹配,TypeScript才抛出类型错误。从报错信息里的类型后缀[][]也能直接看出是数组层级嵌套多了一层。
除此之外你的代码还有两个影响实际运行的小问题:
- 依赖数组漏了回调里用到的
count、t两个外部值,会导致缓存值不会随这两个值更新,出现UI和状态不一致 - 重复冗余的类型标注,同时给变量和useMemo写类型容易出现书写错漏
正确写法
直接删掉useMemo回调里多余的那层方括号,补全依赖,推荐直接给useMemo传入泛型指定返回类型,写法更简洁:
import { useMemo } from 'react'; const bottomSheetOptions = useMemo<BottomSheetAction[]>(() => [ { label: t('kebabMenu.send') + (count > 1 ? t('kebabMenu.documents', { count }) : ''), icon: <SendIcon />, state: sendVisible, dismiss: () => showSendAlert(), onClick: () => showSendAlert(), alertType: 'sendInvoice', disabled: count > 0, visible: documentType === 'sales' }, { label: t('kebabMenu.download'), icon: <DownloadIcon />, state: downloadVisible, dismiss: () => showDownloadDocumentsModal(), onClick: () => showDownloadDocumentsModal(), alertType: 'download', disabled: true, visible: true } ], [ t, count, sendVisible, showSendAlert, documentType, downloadVisible, showDownloadDocumentsModal ]);
注意事项
- 如果
t(i18n翻译函数)、showSendAlert、showDownloadDocumentsModal是用useCallback包裹或者从稳定上下文获取的固定引用,放在依赖数组中不会触发useMemo意外重算,完全符合React Hooks的依赖规则 - 不需要在变量名后面额外写
: BottomSheetAction[]类型标注,TypeScript会根据useMemo的泛型参数自动推导变量类型,减少冗余代码 - 如果项目配置了eslint的
react-hooks/exhaustive-deps规则,按照规则提示补全依赖即可,不要手动遗漏依赖避免出现缓存过期问题
内容的提问来源于stack exchange,提问作者Mikołaj Wittbrodt
相关产品推荐
相关产品推荐

