reactjs - React Hook useEffect 缺少将 redux 操作作为参数的依赖项
问题描述
我在这里发现了许多关于React Hook useEffect has a missing dependency 的类似问题。我已经检查过它们,但我没有找到我所面临的解决方案。我想将redux thunk 函数作为参数传递给React custom hook。
下面是我的代码,它工作正常。但是,我得到了依赖缺失警告,我不想添加忽略警告 eslint。如果我将dispatchAction添加到依赖数组列表中,它会一次又一次地调度,因为 redux thunk asyn 函数已经完成、拒绝、挂起。
自定义挂钩
const useFetchData = (dispatchAction, page) => {
const dispatch = useDispatch();
const [loadMoreLoading, setLoadMoreLoading] = useState(false);
const [errorMsg, setErrorMsg] = useState();
useEffect(() => {
const fetchData = async () => {
setLoadMoreLoading(true);
const resultAction = await dispatch(dispatchAction);
if (resultAction.meta.requestStatus === 'rejected') {
setErrorMsg(resultAction.payload.message);
}
setLoadMoreLoading(false);
};
fetchData();
}, [dispatch, page]);
return [loadMoreLoading, errorMsg]; // it is asking for adding dispatchAction.
我的组件
const SomeListing = ({userId}) => {
const [page, setPage] = useState(1);
const [loadMoreLoading, errorMsg] = useFetchData(
fetchPropertyByUserId({userId: userId, page: page}),
page,
);
}
那么,有什么方法可以在 react 自定义钩子中添加redux thunk 功能?
解决方案
该函数fetchPropertyByUserId
在调用 iefetchPropertyByUserId({userId: userId, page: page})
时返回一个“actionCreator”函数。
因此,当您在 hook 的第一个参数的位置调用此函数时useFetchData
,它每次都会返回一个新的“actionCreator”函数(我们知道在每次渲染时都会调用 hooks):
在SomeListing.jsx 中:
const [loadMoreLoading, errorMsg] = useFetchData(
fetchPropertyByUserId({userId: userId, page: page}), // <-- Here: it returns a new "actionCreator" function at call (render)
page,
);
而且,一旦您将此函数(钩子的第一个参数,即 ie dispatchAction
)作为 的依赖项useEffect
,它应该会导致效果的无限执行,因为现在我们知道,它dispatchAction
会在每次渲染时创建(因此,更改)。
在useFetchData.js 中:
export const useFetchData = (dispatchAction, page) => {
// ...
useEffect(() => {
const fetchData = async () => {
setLoadMoreLoading(true)
const resultAction = await dispatch(dispatchAction)
if (resultAction.meta.requestStatus === 'rejected') {
setErrorMsg(resultAction.payload.message)
}
setLoadMoreLoading(false)
}
fetchData()
}, [dispatch, dispatchAction, page]) // <-- "dispatchAction" added here
// ...
如何解决?
传递一个记忆化的 actionCreator 函数:
在SomeListing.jsx 中:
export const SomeListing = ({ userId }) => {
const [page, setPage] = useState(1)
// Here: "fetchPropertyByUserIdMemo" is memoized now
const fetchPropertyByUserIdMemo = useMemo(
() => fetchPropertyByUserId({ userId: userId, page: page }),
[page, userId]
)
const [loadMoreLoading, errorMsg] = useFetchData(fetchPropertyByUserIdMemo, page)
// ...
}
推荐阅读
- asp.net - ASP.NET jQuery 错误:未知的 Web 方法和无法使用 Visual Studio 2019 调试 aspx Web 表单应用程序
- magento2 - 如何在使用 API 下订单之前更改货币代码
- reactjs - 如何在 Polaris DataTable 中显示来自 Graphiql 对象的订单
- c++ - 在双向链表的末尾插入
- azure-cosmosdb - Gremlin DFS/BFS 搜索同时避免循环
- python-3.x - PyMC3 的哪个 Theano?
- c++ - 谷歌基准框架不优化
- r - R用自定义系数绘制图表
- typescript - 用玩笑酶测试 axios 发布请求
- r - 如何将 summary() 与 lqmm 和公式对象一起使用