在异步action中调用useStore触发无效Hook调用错误如何解决
异步action中调用useStore触发无效Hook调用的解决方案
问题原因
你触发的是第二种报错原因:违反了Hook的使用规则。useStore属于React Hook,只能在React函数组件的顶层或者自定义Hook的顶层调用,你当前将useStore放在了普通的异步action创建函数getCommitsData内调用,该函数不属于上述两个合法调用场景,因此触发报错。
推荐解决方案(适配redux-thunk场景)
绝大多数异步action场景下你不需要调用useStore获取store数据,如果你使用的是redux-thunk中间件,thunk函数默认支持接收getState作为第二个入参,直接调用即可获取全局store的最新状态,修改后代码如下:
export function getCommitsData() { // 移除原有的useStore调用 return async function (dispatch: Function, getState: Function) { try { // 调用getState即可获取完整store数据,无需使用Hook const store = getState(); const commits = await axios.get(`url`); const commitsData = commits.data; dispatch(getCommitsDataAction({ commitsData })); } catch (err) { console.log(err); } }; }
备选解决方案(需在组件内调用Hook)
如果你需要提前在组件侧拿到store数据传给action,将useStore的调用移到触发action的函数组件顶层即可,示例如下:
组件侧代码
import { useStore, useDispatch } from 'react-redux' const DemoComponent = () => { // 组件顶层合法调用Hook const store = useStore() const dispatch = useDispatch() const handleFetch = () => { // 将需要的store数据作为参数传入action dispatch(getCommitsData(store.getState().user.token)) } return <button onClick={handleFetch}>拉取提交数据</button> }
调整后的action代码
// 接收组件传入的store相关参数 export function getCommitsData(token: string) { return async function (dispatch: Function) { try { const commits = await axios.get(`url`, { headers: { Authorization: `Bearer ${token}` } }); const commitsData = commits.data; dispatch(getCommitsDataAction({ commitsData })); } catch (err) { console.log(err); } }; }
其他注意事项
- 原代码中
await console.log(err)属于冗余写法,console.log是同步方法不需要加await前缀 - 所有React Hook都遵循相同的调用规则,禁止在普通函数、循环、条件判断、异步回调内部调用
内容的提问来源于stack exchange,提问作者reijkee
相关产品推荐
相关产品推荐

