Redux-saga调用含useSelector方法报Invalid hook call如何修复
错误原因
你遇到的Invalid hook call. Hooks can only be called inside of the body of a function component报错根源是Hook调用规则违反:
useSelector是React-Redux提供的React Hook,按照React官方规则,Hook只能在React函数组件、自定义Hook的顶层作用域调用- 你把
useSelector写在了普通异步函数save()内部,且这个函数最终在Redux Saga的Generator函数里执行,完全不符合Hook的调用要求,因此直接抛出错误。
修复步骤
1. 改造save函数,移除内部的Hook调用
不要在普通工具函数里用useSelector取store数据,把需要存储的canvas数据作为入参传入save函数即可:
import { firestore as db } from "../../components/firebase/firebase"; import { getAuth } from "firebase/auth"; // 接收外部传入的canvas数据,移除内部useSelector逻辑 export const save = async (canvasData: string) => { const auth: any = getAuth(); await db.collection("images").add({ user: auth.currentUser.displayName, data: canvasData, }); return canvasData; };
2. 在Saga中用内置effect取store数据,调用save
Redux Saga本身提供了select effect用来读取store状态,完全不需要依赖React Hook,改造你的saga代码:
import { takeEvery, put, select } from "redux-saga/effects"; // 保留你原有的其他import,比如save方法、action定义等 export function* imgWorker() { try { // 通过select effect直接从store取canvas数据 const canvasData: string = yield select((state: any) => state.canvas.canvas); // 把取到的数据传入save方法执行存储 const img: string = yield save(canvasData); yield put(saveImgSucceed(img)); } catch (error) { console.log("imgSaga", error); yield put(saveImgFailed()); } } export function* saveImg() { yield takeEvery(GET_IMAGE_DATA, imgWorker); }
注意:所有React Hook(包含useState、useSelector、useEffect等)都不能在普通工具函数、循环、条件判断、Saga Generator函数这类非React组件/自定义Hook的场景下调用,这类场景下要读取Redux store,要么通过saga的select effect,要么直接从store实例上调用
store.getState()取值。
内容的提问来源于stack exchange,提问作者Gg Wp
相关产品推荐
相关产品推荐

