Next.js集成Redux栈调用dispatch报无效Hook错误如何解决
存在的问题
- 违反React Hook调用规则。
useAppDispatch是React自定义Hook,只能在函数组件的顶层作用域调用,不能在条件判断块、事件回调函数这类嵌套场景中调用。你当前有两处错误调用:一是在switchSelection用户交互回调中直接调用useAppDispatch,二是在组件内部的if (invoiceItems)条件块中调用useAppDispatch,这是触发Invalid hook call报错的直接原因。 - Redux切片的Action类型定义错误。你声明
setInvoiceItems的载荷类型是{ InvoiceItemData? },但实际传入的是字符串为键、数值为值的InvoiceItemDataOnBuyTicket类型,类型不匹配。 - useAppSelector取值路径错误。你的切片名称为
StartPaymentIn,取数时需要先通过切片名访问对应状态,直接写state.invoiceItems会拿不到预期值。
修复步骤
- 组件顶层调用
useAppDispatch获取dispatch实例,后续所有触发Action的场景都复用这个实例:
const InvoiceItemsToDeliver = (props: ProductProps) => { // 顶层调用Hook获取dispatch方法 const dispatch = useAppDispatch(); // 修正selector取数路径 const itemsWithSelection2 = useAppSelector((state) => state.StartPaymentIn.invoiceItems); // 其他原有逻辑... }
- 把条件判断中的初始化dispatch逻辑放到
useEffect中执行,避免在组件渲染流程中执行副作用:
useEffect(() => { if (invoiceItems && !itemsWithSelection2) { dispatch(setInvoiceItems(invoiceItems2)); } }, [invoiceItems, itemsWithSelection2, dispatch]);
- 修改
switchSelection回调中的调用逻辑,用顶层拿到的dispatch实例触发Action:
const switchSelection = (key) => { let itemsWithSelection2; if (itemsWithSelection) { itemsWithSelection2 = { ...itemsWithSelection }; } else { itemsWithSelection2 = Object.fromEntries( Object.keys(invoiceItemsFiltered) .filter((key) => invoiceItems[key].defaultValue != undefined) .map((key) => [key, invoiceItems[key].defaultValue]) ); } itemsWithSelection2[key] = itemsWithSelection2[key] == 1 ? 0 : 1; setItemsWithSelection(itemsWithSelection2); // 替换原有的useAppDispatch调用 dispatch(setInvoiceItems(itemsWithSelection2)); };
- 修正切片的Action载荷类型:
const StartPaymentInSlice = createSlice({ name: "StartPaymentIn", initialState, reducers: { setInvoiceItems(state, action: PayloadAction<InvoiceItemDataOnBuyTicket>) { state.invoiceItems = action.payload; }, }, });
内容的提问来源于stack exchange,提问作者János
相关产品推荐
相关产品推荐

