useEffect使用清理函数报arrow function expected no return value警告如何修复

警告触发原因
该警告是ESLint/TypeScript的consistent-return(一致返回)规则触发的,问题出在你传入useEffect的箭头函数存在两种不一致的返回行为:
- 当
!currentUser || !talkjsContainerRef.current条件成立时,你直接执行return;,此时返回值为undefined - 当条件不成立时,代码执行到末尾,返回值为清理函数类型
虽然React本身允许useEffect的回调返回undefined或者清理函数,但Lint规则要求同一箭头函数的所有返回路径必须返回相同类型的值,因此触发了警告。
修复方案(保留清理函数的前提下)
方案1:对齐提前返回的类型
把提前返回的语句改为显式返回undefined,匹配所有路径的返回值类型要求,代码改动最小:
// 把原有的提前返回行 if (!currentUser || !talkjsContainerRef.current) return; // 改为 if (!currentUser || !talkjsContainerRef.current) return undefined;
方案2:调整代码结构避免提前返回
把所有业务逻辑都包裹在条件成立的代码块内,不做提前返回,同时建议给inbox添加undefined类型标注,避免未赋值的类型隐患:
useEffect(() => { const { currentUser } = initialState!; let inbox: Talk.Inbox | undefined; // 把原有提前返回的判断反过来,包裹业务逻辑 if (currentUser && talkjsContainerRef.current) { Talk.ready.then(async () => { const me = employeeToUser(currentUser); window.talkSession = new Talk.Session({ appId, me }); if (id === undefined) { inbox = window.talkSession.createInbox(); } else { const other = employeeToUser(await readEmployee(Number(id))); const conversation = window.talkSession.getOrCreateConversation(Talk.oneOnOneId(me, other)); conversation.setParticipant(me); conversation.setParticipant(other); inbox = window.talkSession.createInbox({ selected: conversation }); } inbox.mount(talkjsContainerRef.current); }); } return () => { inbox?.destroy(); }; }, [id, initialState]);
方案3:显式标注函数返回类型
直接给useEffect的回调函数加上返回类型声明,告诉TypeScript你明确知道该函数会返回undefined或者清理函数,无需做返回一致性校验:
// 仅在回调函数开头加返回类型标注即可,原有逻辑不需要改动 useEffect((): void | (() => void) => { const { currentUser } = initialState!; let inbox: Talk.Inbox; if (!currentUser || !talkjsContainerRef.current) return; Talk.ready.then(async () => { const me = employeeToUser(currentUser); window.talkSession = new Talk.Session({ appId, me }); if (id === undefined) { inbox = window.talkSession.createInbox(); } else { const other = employeeToUser(await readEmployee(Number(id))); const conversation = window.talkSession.getOrCreateConversation(Talk.oneOnOneId(me, other)); conversation.setParticipant(me); conversation.setParticipant(other); inbox = window.talkSession.createInbox({ selected: conversation }); } inbox.mount(talkjsContainerRef.current); }); return () => { inbox?.destroy(); }; }, [id, initialState]);
方案4:临时忽略规则校验(仅应急使用)
如果不想修改代码逻辑,可以在useEffect上方加注释临时禁用该条Lint规则,不建议长期使用:
// eslint-disable-next-line consistent-return useEffect(() => { // 原有代码不变 }, [id, initialState]);
内容的提问来源于stack exchange,提问作者Loi Nguyen Huynh
相关产品推荐
相关产品推荐

