redux React钩子:dispatch action from useEffect

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

我的文件夹结构:

|--App
  |--Components
    |--PageA.js
    |--PageB.js
    |--PageC.js
  |--common-effects
    |--useFetching.js

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

  • PageA.js*:
function(props) {
  useFetching(actionParams)
  //....//
}

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

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

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


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

ygya80vv

ygya80vv1#

使用react-redux钩子的版本:

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

export default function MyComponent() {
  useFetching(fetchSomething);

  return <div>Doing some fetching!</div>
}

字符串
用你的定制钩子

import { useDispatch } from 'react-redux';

const useFetching = (someFetchActionCreator) => {
  const dispatch = useDispatch();
  useEffect(() => {
    dispatch(someFetchActionCreator());
  }, [])
}

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

s8vozzvw

s8vozzvw2#

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

function MyComponent(props) {
    useFetching(props.fetchSomething);

    return <div>Doing some fetching!</div>
}

const mapDispatch = {
    fetchSomething
};

export default connect(null, mapDispatch)(MyComponent);

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

const useFetching = someFetchActionCreator => {
  useEffect( () => {
    someFetchActionCreator();
  }, [])
}

nwnhqdif

nwnhqdif3#

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

import { useDispatch } from 'react-redux';

const useFetching = (someFetchActionCreator) => {
    const dispatch = useDispatch()

    useEffect(() => {
        dispatch(someFetchActionCreator());
    }, [])
}

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

vngu2lb8

vngu2lb84#

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

import React, { useEffect } from 'react'
  import { useDispatch } from 'react-redux'
  import axios from 'axios'
  import { getItemsStart, getItemsSuccess, getItemsFailure } from '../features/itemsSlice'

  const fetchItems = () => async dispatch => {
    try {
      dispatch(getItemsStart());
      const { data } = await axios.get('url/api')
      dispatch(getItemsSuccess(data))
    } catch (error) {
      dispatch(getItemsFailure(error))
    }
  }

  const PageA = () => {
    const dispatch = useDispatch()
    const { items } = useSelector(state => state.dataSlice)
   
    useEffect(() => {
       dispatch(fetchItems())
    }, [dispatch])

    return (
      <ul>
         {items.map(item => <li>{item.name}</li>}
      </ul> 
    )
  }
  
  export default PageA

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

44u64gxh

44u64gxh5#

useEffect(() => {
   fetchData();
 }, []);

 async function fetchData() {
   try {
     await Auth.currentSession();
     userHasAuthenticated(true);
   } catch (e) {
     if (e !== "No current user") {
       alert(e);
     }
   }
   dispatch(authentication({ type: "SET_AUTHING", payload: false }));
 }

字符串

相关问题