使用createAsyncThunk分发AsyncThunk时遇无效Hook调用错误求助
嘿,我看到你在结合Redux Thunk做异步状态管理时卡壳了,先从那个最显眼的Hook错误说起——这其实是个容易忽略的小细节,但确实会触发React的错误提示!
1. 直接修复Hook调用错误
在你的Counter.tsx组件里,这句代码有问题:
const dispatch = useDispatch
useDispatch是React-Redux提供的Hook,**必须调用它(加上括号)**才能正确获取dispatch函数。正确写法应该是:
const dispatch = useDispatch();
你之前只是引用了Hook函数本身,没有执行调用,违反了React Hooks的调用规则,这就是触发Invalid hook call错误的直接原因。
2. 修正mapDispatch的错误写法
你的mapDispatch定义也存在问题:
const mapDispatch = { increment : () => ({ type: increment }), decrement : () => ({ type : decrement }), incrementByAmount : (value : number) => ({type: incrementByAmount, payload: 5}) }
这里不需要手动创建action对象,因为increment、decrement这些都是Redux Toolkit的createSlice生成的action creator函数,直接传递给mapDispatch即可,connect会自动帮你把它们包装成带有dispatch的调用函数。正确写法是:
const mapDispatch = { increment, decrement, incrementByAmount }
另外你之前的incrementByAmount不管传入什么参数,payload都是固定的5,修复后调用props.incrementByAmount(5)就能正确把5作为payload传递给reducer了。
3. 可选:改用更简洁的Hooks写法(替代connect)
既然你已经在使用useDispatch,其实可以完全抛弃connect,改用React-Redux的useSelector和useDispatch组合,代码会更简洁直观:
import { FC } from "react"; import { Button, Text, View } from "react-native" import { useSelector, useDispatch } from "react-redux" import { AppState } from "../Reducers/RootReducer" import { increment, decrement, incrementByAmount, delayedIncrement} from "../Reducers/CounterReducer"; interface CounterProps { a : string } const Counter : FC<CounterProps> = (props) => { // 直接用useSelector获取状态 const counter = useSelector((state: AppState) => state.counter.num); const dispatch = useDispatch(); return ( <View> <Text>{props.a}</Text> <Text>{counter.toString()}</Text> <Button title="increment" onPress={() => dispatch(increment())} /> <Button title="decrement" onPress={() => dispatch(decrement())} /> <Button title="increment5" onPress={() => dispatch(incrementByAmount(5))} /> <Button title="delayed" onPress={() => dispatch(delayedIncrement(5))} /> </View> ) } export default Counter;
4. 可选:用Redux Toolkit的configureStore简化Store配置
你的RootReducer.tsx里用了createStore和手动添加thunk中间件,其实Redux Toolkit的configureStore已经默认集成了thunk,不需要手动配置,代码可以简化:
import { combineReducers, configureStore } from "@reduxjs/toolkit"; import counterReducer from "./CounterReducer" export const rootReducer = combineReducers({ counter: counterReducer }) export type AppState = ReturnType<typeof rootReducer> // configureStore自动包含thunk中间件,无需手动applyMiddleware export const store = configureStore({ reducer: rootReducer, })
最后检查
修改完上面的点后,点击delayed按钮应该就能正常触发异步操作,5秒后计数器会增加5了。如果还有问题,可以检查:
- 确保你的React和React-Redux版本匹配(Redux Toolkit要求React 16.8+,因为依赖Hooks)
- 确认项目中没有多个React副本(可以通过
npm ls react命令检查)
内容的提问来源于stack exchange,提问作者manywows

