React Hooks:useEffect的分派动作

时间:2019-02-28 16:28:31

标签: javascript reactjs redux redux-saga

我的文件夹结构:

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

我正在使用react hooks重构代码以从API提取数据。 我想从 saga 中间件拦截的 useFetching.js 中的 useEffect 调度一个动作。仅在安装组件( PageA PageB PageC )时分派该动作。

我正在使用 redux react-redux redux-saga

PageA.js

function(props) {
  useFetching(actionParams)
  //....//
}

PageB PageC 组件的相似代码。

我已经抽象出可重用的代码以在useFetching 自定义挂钩中获取数据。

useFetching.js

const useFetching = actionArgs => {
  useEffect( () => {
    store.dispatch(action(actionArgs)); // does not work
  })
}

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

5 个答案:

答案 0 :(得分:13)

使用react-redux钩子的版本:

您甚至可以使用react-redux中的 useDispatch 完全切断连接功能:

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的建议从自定义钩子中删除了分派

注意:React保证调度功能的身份是稳定的,并且在重新渲染时不会更改。这就是为什么可以安全地从useEffect或useCallback依赖项列表中省略的原因。

答案 1 :(得分:4)

您需要将绑定动作创建者或对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();
  }, [])
}

答案 2 :(得分:3)

亚历克斯·汉斯(Alex Hans)可以通过分派做出正确的决定,但是要消除对api的请求循环,您可以指定对分派的依赖性(我使用Redux Toolkit

    ActionBar actionBar = getSupportActionBar();
    actionBar.hide();

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

答案 3 :(得分:2)

这只是为@Alex Hans的答案带来一些优化。

根据文档here。自定义挂钩是一种JavaScript函数,其名称以“ use”开头,并且可以调用其他挂钩。

考虑到这一点,我们不需要将对派发函数的引用作为参数发送到useFetching挂钩,而是简单地不发送它,而只是在useFetching挂钩中使用适当的导入使用它。

这是我的意思的摘录。

import { useDispatch } from 'react-redux';

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

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

我无法确定此示例是否适合您的情况,而不会引起您代码库中的错误,而只是试图解释这篇文章背后的想法/概念。

希望这对将来的人都有帮助。

答案 4 :(得分:0)

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 }));
 }
相关问题