Javascript 反应钩子:从 useEffect 分派动作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/54930197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React hooks: dispatch action from useEffect
提问by HarshvardhanSharma
My folder structure:
我的文件夹结构:
|--App
|--Components
|--PageA.js
|--PageB.js
|--PageC.js
|--common-effects
|--useFetching.js
I am refactoring my code to fetch data from API, using react hooks. I want to dispatch an action from useEffectin useFetching.jsthat is intercepted by sagamiddleware. The action should be dispatched only when the components(PageA, PageB, PageC) mount.
我正在重构我的代码以使用 react hooks从 API 获取数据。我想从useFetching.js中的useEffect调度一个被saga中间件拦截的动作。仅当组件(PageA、PageB、PageC)安装时才应分派该操作。
I am using redux, react-reduxand redux-saga.
我正在使用redux、react-redux和redux-saga。
PageA.js:
页面A.js:
function(props) {
useFetching(actionParams)
//....//
}
Similar code for PageBand PageCcomponents.
PageB和PageC组件的类似代码。
I have abstracted the reusable code to fetch data in useFetchingCustom hook.
我已经抽象了可重用的代码以在useFetchingCustom hook 中获取数据。
useFetching.js
使用Fetching.js
const useFetching = actionArgs => {
useEffect( () => {
store.dispatch(action(actionArgs)); // does not work
})
}
I don't know how to access redux dispatchin useFetching. I tried it with useReducereffect, but the sagas missed the action.
我不知道如何dispatch在useFetching 中访问 redux 。我试了一下,useReducer效果不错,但传奇错过了动作。
回答by Alex Hans
Version using react-redux hooks:
使用 react-redux 钩子的版本:
You can even cut out the connect function completely by using useDispatchfrom react-redux:
你甚至可以通过使用useDispatchfrom react-redux来完全切断连接功能:
export default function MyComponent() {
useFetching(fetchSomething);
return <div>Doing some fetching!</div>
}
with your custom hook
使用您的自定义挂钩
import { useDispatch } from 'react-redux';
const useFetching = (someFetchActionCreator) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(someFetchActionCreator());
}, [])
}
Edit:removed dispatch from custom hook as suggested by @yonga-springfield
编辑:按照@yonga-springfield 的建议从自定义钩子中删除调度
Note:React guarantees that dispatch function identity is stable and won't change on re-renders. This is why it's safe to omit from the useEffect or useCallback dependency list.
注意:React 保证 dispatch 函数标识是稳定的并且不会在重新渲染时改变。这就是为什么从 useEffect 或 useCallback 依赖项列表中省略是安全的。
回答by markerikson
You would need to pass either bound action creators or a reference to dispatchto your hook. These would come from a connected component, same as you would normally use React-Redux:
您需要传递绑定动作创建者或dispatch对钩子的引用。这些将来自一个连接的组件,就像你通常使用 React-Redux 一样:
function MyComponent(props) {
useFetching(props.fetchSomething);
return <div>Doing some fetching!</div>
}
const mapDispatch = {
fetchSomething
};
export default connect(null, mapDispatch)(MyComponent);
The hook should then call the bound action creator in the effect, which will dispatch the action accordingly.
然后钩子应该调用效果中的绑定动作创建者,这将相应地分派动作。
Also, note that your current hook will re-run the effect everytime the component is re-rendered, rather than just the first time. You'd need to modify the hook like this:
另外,请注意,每次重新渲染组件时,您当前的钩子都会重新运行效果,而不仅仅是第一次。您需要像这样修改钩子:
const useFetching = someFetchActionCreator => {
useEffect( () => {
someFetchActionCreator();
}, [])
}
回答by yonga springfield
This is just to bring some optimization to @Alex Hans' answer.
这只是为了对@Alex Hans 的回答进行一些优化。
As per the documentation here. A custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks.
根据此处的文档。自定义 Hook 是一个 JavaScript 函数,其名称以“use”开头,并且可以调用其他 Hook。
With this in mind, we need not send a reference to the dispatch function to the useFetching hook as a parameter but rather, simply not send it and rather simply use it from within the useFetching hook with the appropriate imports.
考虑到这一点,我们不需要将调度函数的引用作为参数发送到 useFetching 钩子,而是简单地不发送它,而是简单地从带有适当导入的 useFetching 钩子中使用它。
Here's an excerpt of what I mean.
这是我的意思的摘录。
import { useDispatch } from 'react-redux';
const useFetching = (someFetchActionCreator) => {
const dispatch = useDispatch()
useEffect(() => {
dispatch(someFetchActionCreator());
}, [])
}
I can't ascertain this example will fit without errors in your codebase in your case but just trying to explain the idea/concept behind this post.
我无法确定这个示例是否适合您的代码库中没有错误,但只是试图解释这篇文章背后的想法/概念。
Hope this helps any future comer.
希望这对任何未来的人都有帮助。
回答by Asgar Ali Khachay
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 }));
}

