关于React Redux中dispatch及异步action的技术疑问咨询
React Redux 疑问解答(基于你的代码实现)
你的疑问及解答
1. dispatch函数的返回值是什么?
dispatch的返回值分两种情况:- 如果传入的是普通同步action对象,返回值就是这个action对象本身;
- 如果传入的是Thunk函数(比如你调用
dispatch(setDataBlog())时传入的就是setDataBlog返回的函数),dispatch会执行这个Thunk函数,返回值是Thunk函数的执行结果——也就是你里面axios请求的Promise对象。另外,你在Thunk内部调用dispatch(action)时,返回的是这个action对象。
2. 为何homeAction.js中要将setDataBlog写成双层箭头函数的形式?
这是Redux Thunk中间件的要求。Thunk允许我们创建异步action creator:- 第一层箭头函数可以用来接收外部传入的参数(比如如果需要根据某个id请求数据,就能在这里传id);
- 第二层箭头函数会被Thunk中间件自动注入dispatch(和getState)参数,让我们能在异步操作完成后,调用dispatch发送同步action去更新store。如果只写单层函数,就没法拿到dispatch,也没法处理异步逻辑。
3. setDataBlog内部的dispatch参数来自哪里?
这个dispatch是Redux Thunk中间件传递过来的。当你调用dispatch(setDataBlog())时,setDataBlog返回的函数会被Thunk捕获,Thunk会自动把Redux store的dispatch方法作为参数传给这个内部函数,让你能在异步逻辑里使用它来发送action。4. 为何在setDataBlog内部还要再次调用dispatch?
因为setDataBlog的作用是处理异步请求(比如从API拿数据),但真正能让Redux store更新的只有同步action对象。当你拿到API返回的有效数据后,必须调用dispatch把包含数据的同步action(比如{ type: "UPDATE_DATA_BLOG", payload: responseAPI.data })发给reducer,reducer才能根据这个action的类型和数据来更新store里的dataBlog状态,组件通过useSelector才能拿到最新的数据渲染页面。
相关代码实现
Home组件代码
import React, { Fragment, useEffect } from "react"; import { useDispatch, useSelector } from "react-redux"; import { ArticleListSection } from "../../components"; import { ArticlesCard, Hero } from "../../components/molecules"; import { setDataBlog } from "../../config/redux/action"; export const Home = () => { const { dataBlog } = useSelector((state) => state.homeReducer); const dispatch = useDispatch(); useEffect(() => { dispatch(setDataBlog()); }, [dispatch]); return ( <Fragment> <Hero titleHero="Kemal is a place to write, read, and connect." descHero="It's easy and free to post your thinking on any topic and connect with millions of readers." button="Start Writing!" ></Hero> <ArticlesCard dataBlog={dataBlog}></ArticlesCard>; <ArticleListSection dataBlog={dataBlog}></ArticleListSection> </Fragment> ); }; export default Home;
homeAction.js原始代码
import Axios from "axios"; export const setDataBlog = () => (dispatch) => { console.log({ dispatch }); Axios.get("http://localhost:4000/v1/blog/posts") .then((result) => { const responseAPI = result.data; dispatch(); }) .catch((err) => { console.log("error: ", err); }); };
改写后的setDataBlog代码
export const setDataBlog = () =>{ return(dispatch)=>{ Axios.get("http://localhost:4000/v1/blog/posts") .then((result) => { const responseAPI = result.data; dispatch({ type: "UPDATE_DATA_BLOG", payload: responseAPI.data }); }) .catch((err) => { console.log("error: ", err); }); } }
内容的提问来源于stack exchange,提问作者KEMAL TAUFIK FIKRI -
相关产品推荐
相关产品推荐

