:::info 在业务组件使用redux、react-redux的过程是比较复杂的。
所以我们使用使用react-redux中的hooks来完成。 :::

1、在业务组件中,使用Hook发送网络请求

  1. import React, { memo, useEffect } from 'react';
  2. // 后台接口api的封装
  3. import { getTopBanner } from "@/service/config/home";
  4. export default function Recommend() {
  5. // 使用hooks 获取数据
  6. useEffect(() => {
  7. getTopBanner({ url: "/banner"}).then(res => {
  8. // 得到获取的结果数据 这里请求的结果数据 可以直接在页面中进行相应的渲染
  9. console.log(res)
  10. })
  11. }, []) // 第二个参数是我们要依赖的数据
  12. return (
  13. <div>
  14. <h2>推荐</h2>
  15. </div>
  16. )
  17. };

2、redux在模块中详细使用的流程

2.1 实际的业务组件

  1. import React, { memo, useEffect } from 'react';
  2. // 引入connect
  3. import { connect } from "react-redux";
  4. // 引入派发的函数
  5. import { getTopBannerAction } from "./store/actionCreateors";
  6. function Recommend(props) {
  7. const { topBanner, getTopBanner } = props;
  8. // 在hook中发送网络请求
  9. useEffect(() => {
  10. getTopBanner()
  11. }, [getTopBanner])
  12. return (
  13. <div>
  14. <h2>推荐</h2>
  15. <h2>{ topBanner.length }</h2>
  16. </div>
  17. )
  18. };
  19. const mapStateToProps = state => {
  20. return {
  21. topBanner: state.recommend.topBanners
  22. }
  23. }
  24. const mapDispatchToProps = dispatch => {
  25. return {
  26. getTopBanner() {
  27. // 这里派发这个函数
  28. dispatch(getTopBannerAction())
  29. }
  30. }
  31. }
  32. // 将组件导出
  33. export default connect(mapStateToProps, mapDispatchToDispatch)(memo(Recommend));

2.2 actionCreators文件

  1. // 常量
  2. import { CHANGE_TOP_BANNER } from "./constants";
  3. import { getTopBanner } from "@/service/recommend";
  4. // 改变状态的action
  5. const changeBannerAction = banner => {
  6. return {
  7. type: CHANGE_TOP_BANNER,
  8. banner
  9. }
  10. }
  11. // 组件派发的函数 使用函数的形式 可以传递某些参数进来
  12. const getTopBannerAction = () => {
  13. return dispatch => {
  14. // 发送网络请求
  15. getTopBanner().then(res => {
  16. const banner = res.banners;
  17. // 在这里可以dispatch派发action 调用reducer函数来更改状态
  18. dispatch(changeBannerAction(banner))
  19. })
  20. }
  21. }
  22. export { getTopBannerAction };

2.3 子reducer文件

  1. // 常量
  2. import { CHANGE_TOP_BANNER } from "./constants";
  3. // 初始化的值
  4. const initialState = {
  5. topBanners: []
  6. }
  7. function reducer(state = initialState, action) {
  8. switch(action.type) {
  9. case CHANGE_TOP_BANNER:
  10. return {...state, topBanners: action.banner}
  11. default:
  12. return state;
  13. }
  14. }
  15. // 将reducer函数进行到处
  16. export default reducer;

3、在react-redux中使用hooks

  1. // 引入组件中的hooks
  2. import React, { memo, useEffect } from 'react';
  3. // 引入react-redux中的hooks
  4. import { useDispatch, useSelector, shallowEqual } from "react-redux";
  5. // 引入派发的函数
  6. import { getTopBannerAction } from "./store/actionCreateors";
  7. function Recommend() {
  8. // 在业务组件中使用hook来获 我们需要的状态数据
  9. const recommend = useSelector(state => {
  10. return {
  11. topBanners: state.recommend.topBanners
  12. }
  13. }, shallowEqual);
  14. // 获取banner中的数据 直接进行解构与赋值
  15. const { topBanners } = recommend;
  16. // 使用hook来获取dispatch
  17. const dispatch = useDispatch()
  18. // 在hook中发送网络请求
  19. useEffect(() => {
  20. // 直接派发action
  21. dispatch(getTopBannerAction())
  22. }, [dispatch])
  23. return (
  24. <div>
  25. <h2>推荐</h2>
  26. <h2>{ topBanners.length }</h2>
  27. </div>
  28. )
  29. };
  30. // 将组件导出
  31. export default memo(Recommend);
  32. // 需要注意的是 这两个hooks是从react-redux中导入的
  33. import { useSelector, useDispatch, shallowEqual } from "react-redux";
  34. // react-redux中hooks的使用总结
  35. // 不再使用connect函数了
  36. // 直接使用const state = useSelector(() => {}, shallowEqual) 来代替mapStateToProps
  37. // 直接使用const dispatch = useDispatch() 来代替mapDispatchToDispatch
  38. const mapStateToProps = state => {
  39. return {
  40. topBanners: state.recommend.topBanners
  41. }
  42. }
  43. // 上述使用hook来完成 得到的属性可以直接在组件中进行使用
  44. const { topBanners } = useSelector(state => {
  45. return {
  46. topBanners: state.recommend.topBanners
  47. }
  48. }, shallowEqual)
  49. // 说明 第一个参数是传入我们的state, 返回我们需要获取的数,这个返回的结果我们可以直接进行使用,也就是我们组件需要使用的数据。
  50. const mapDispatchToProps = dispatch => {
  51. return {
  52. getTopBanner() {
  53. // 直接派发action
  54. dispatch(getTopBannerAction)
  55. }
  56. }
  57. }
  58. // 上述代码 使用useDispatch来改造
  59. const dispatch = useDispatch();
  60. // 可以直接派发action
  61. dispatch(getTopBannerAction)
  62. // 在hook中发送网络请求
  63. useEffect(() => {
  64. // 直接派发action
  65. dispatch(getTopBannerAction())
  66. }, [dispatch])

:::info react-redux中的hooks使用总结:使用非常的简洁

  • 使用useSelector来代替原来的mapStateToProps。在使用useSelector的时候可以传入第二个参数shallowEqual来进行浅层比较,对代码进行性能优化。
  • 使用useDispatch来代替原理的mapDispatchToprops。 :::

3.1 useSelector hook的使用

  1. // redux中的两个非常重要的hook About组件
  2. import React from 'react';
  3. import { useEffect } from 'react';
  4. import { useSelector, useDispatch } from "react-redux";
  5. import {
  6. incrementAction,
  7. addNumberAction,
  8. getSyncHomeData
  9. } from "../../store/actionCreators";
  10. function About(props) {
  11. // 使用useSelector来代替mapStateToProps的功能
  12. const count = useSelector(state => state.count)
  13. // 使用useDispatch hook来代替mapStateToDispatch
  14. const dispatch = useDispatch();
  15. function increment() {
  16. dispatch(incrementAction());
  17. }
  18. function incrementNumber() {
  19. dispatch(addNumberAction(10));
  20. }
  21. // 获取异步数据
  22. useEffect(() => {
  23. // 派发action
  24. dispatch(getSyncHomeData);
  25. }, [dispatch])
  26. return (
  27. <div>
  28. <h2>About组件4--{count}</h2>
  29. <button onClick={increment}>+1</button>
  30. <button onClick={incrementNumber}>+10</button>
  31. </div>
  32. )
  33. }
  34. export default About;

3.2 useDispatch hook的详细使用

  1. // Home组件
  2. import React from 'react';
  3. import { useSelector, useDispatch } from "react-redux";
  4. import {
  5. decrementAction,
  6. subNumberAction
  7. } from "../../store/actionCreators"
  8. function Home() {
  9. // 使用useSelector来代替mapStateToProps
  10. const state = useSelector(state => {
  11. return {
  12. count: state.count,
  13. banner: state.banner,
  14. recommend: state.recommend
  15. }
  16. })
  17. // 使用useDispatch hook函数来代替mapStateToDispatch
  18. const dispatch = useDispatch();
  19. function decrement() {
  20. dispatch(decrementAction())
  21. }
  22. function decrementNumber() {
  23. dispatch(subNumberAction(10))
  24. }
  25. return (
  26. <div>
  27. <h2>Home组件4--{state.count}</h2>
  28. <button onClick={decrement}>-1</button>
  29. <button onClick={decrementNumber}>-10</button>
  30. <h2>轮播数据</h2>
  31. <ul>
  32. {
  33. state.banner.map(item => {
  34. return <li key={item.acm}>{item.title}</li>
  35. })
  36. }
  37. </ul>
  38. <h2>推荐数据</h2>
  39. <ul>
  40. {
  41. state.recommend.map(item => {
  42. return <li key={item.acm}>{item.title}</li>
  43. })
  44. }
  45. </ul>
  46. </div>
  47. )
  48. }
  49. export default Home;