redux React钩子:dispatch action from useEffect

nwsw7zdq  于 2023-08-05  发布在  React
关注(0)|答案(5)|浏览(160)

我的文件夹结构:

  1. |--App
  2. |--Components
  3. |--PageA.js
  4. |--PageB.js
  5. |--PageC.js
  6. |--common-effects
  7. |--useFetching.js

字符串
我正在重构我的代码,以使用react hooks从API获取数据。我想调度** Saga 中间件截获的useFetching.js*useEffect的action。仅当组件(PageAPageBPageC)装入时才应分派操作。
我使用的是
redux**、react-reduxredux-saga

  • PageA.js*:
  1. function(props) {
  2. useFetching(actionParams)
  3. //....//
  4. }

  • PageB* 和 PageC 组件的类似代码。

我已经抽象了可重用代码,以在useFetching * 自定义钩子 * 中获取数据。

  • 使用Fetching.js*
  1. const useFetching = actionArgs => {
  2. useEffect( () => {
  3. store.dispatch(action(actionArgs)); // does not work
  4. })
  5. }


我不知道如何在 useFetching 中访问redux dispatch。我尝试了useReducer效果,但传奇错过了行动。

ygya80vv

ygya80vv1#

使用react-redux钩子的版本:

你甚至可以使用react-redux中的**useDispatch**来完全去掉connect函数:

  1. export default function MyComponent() {
  2. useFetching(fetchSomething);
  3. return <div>Doing some fetching!</div>
  4. }

字符串
用你的定制钩子

  1. import { useDispatch } from 'react-redux';
  2. const useFetching = (someFetchActionCreator) => {
  3. const dispatch = useDispatch();
  4. useEffect(() => {
  5. dispatch(someFetchActionCreator());
  6. }, [])
  7. }

**编辑:**根据@yonga-springfield的建议,从自定义钩子中删除了dispatch
**注意:**React保证dispatch函数标识是稳定的,不会在重新渲染时改变。这就是为什么从useEffect或useCallback依赖项列表中省略是安全的。

展开查看全部
s8vozzvw

s8vozzvw2#

您需要将绑定的动作创建者或dispatch的引用传递给您的钩子。这些将来自一个连接的组件,就像你通常使用React-Redux一样:

  1. function MyComponent(props) {
  2. useFetching(props.fetchSomething);
  3. return <div>Doing some fetching!</div>
  4. }
  5. const mapDispatch = {
  6. fetchSomething
  7. };
  8. export default connect(null, mapDispatch)(MyComponent);

字符串
然后,钩子应该调用效果中的绑定动作创建器,这将相应地分派动作。
另外,请注意,您当前的钩子将在组件重新呈现时 * 每次 * 重新运行效果,而不仅仅是第一次。你需要像这样修改钩子:

  1. const useFetching = someFetchActionCreator => {
  2. useEffect( () => {
  3. someFetchActionCreator();
  4. }, [])
  5. }

展开查看全部
nwnhqdif

nwnhqdif3#

这只是为了给@Alex Hans的答案带来一些优化。
根据这里的文档。自定义Hook是一个JavaScript函数,其名称以“use”开头,并且可以调用其他Hook。
考虑到这一点,我们不需要将对分派函数的引用作为参数发送到useFetching钩子,而是简单地不发送它,而是简单地从useFetching钩子中使用它并使用适当的导入。
以下是我的意思的摘录。

  1. import { useDispatch } from 'react-redux';
  2. const useFetching = (someFetchActionCreator) => {
  3. const dispatch = useDispatch()
  4. useEffect(() => {
  5. dispatch(someFetchActionCreator());
  6. }, [])
  7. }

字符串
我不能确定这个例子是否适合你的代码库中没有错误,但只是试图解释这篇文章背后的想法/概念。
希望这对未来的人有所帮助。

展开查看全部
vngu2lb8

vngu2lb84#

Alex Hans正确地决定使用dispatch,但是为了消除对API的请求循环,您可以指定对dispatch的依赖(我使用Redux Toolkit

  1. import React, { useEffect } from 'react'
  2. import { useDispatch } from 'react-redux'
  3. import axios from 'axios'
  4. import { getItemsStart, getItemsSuccess, getItemsFailure } from '../features/itemsSlice'
  5. const fetchItems = () => async dispatch => {
  6. try {
  7. dispatch(getItemsStart());
  8. const { data } = await axios.get('url/api')
  9. dispatch(getItemsSuccess(data))
  10. } catch (error) {
  11. dispatch(getItemsFailure(error))
  12. }
  13. }
  14. const PageA = () => {
  15. const dispatch = useDispatch()
  16. const { items } = useSelector(state => state.dataSlice)
  17. useEffect(() => {
  18. dispatch(fetchItems())
  19. }, [dispatch])
  20. return (
  21. <ul>
  22. {items.map(item => <li>{item.name}</li>}
  23. </ul>
  24. )
  25. }
  26. export default PageA

字符串
在useEffect(()=> {...},[dispatch])中传递dispatch的依赖参数很重要

展开查看全部
44u64gxh

44u64gxh5#

  1. useEffect(() => {
  2. fetchData();
  3. }, []);
  4. async function fetchData() {
  5. try {
  6. await Auth.currentSession();
  7. userHasAuthenticated(true);
  8. } catch (e) {
  9. if (e !== "No current user") {
  10. alert(e);
  11. }
  12. }
  13. dispatch(authentication({ type: "SET_AUTHING", payload: false }));
  14. }

字符串

相关问题