:::info
在业务组件使用redux、react-redux的过程是比较复杂的。
所以我们使用使用react-redux中的hooks来完成。
:::
1、在业务组件中,使用Hook发送网络请求
import React, { memo, useEffect } from 'react';
// 后台接口api的封装
import { getTopBanner } from "@/service/config/home";
export default function Recommend() {
// 使用hooks 获取数据
useEffect(() => {
getTopBanner({ url: "/banner"}).then(res => {
// 得到获取的结果数据 这里请求的结果数据 可以直接在页面中进行相应的渲染
console.log(res)
})
}, []) // 第二个参数是我们要依赖的数据
return (
<div>
<h2>推荐</h2>
</div>
)
};
2、redux在模块中详细使用的流程
2.1 实际的业务组件
import React, { memo, useEffect } from 'react';
// 引入connect
import { connect } from "react-redux";
// 引入派发的函数
import { getTopBannerAction } from "./store/actionCreateors";
function Recommend(props) {
const { topBanner, getTopBanner } = props;
// 在hook中发送网络请求
useEffect(() => {
getTopBanner()
}, [getTopBanner])
return (
<div>
<h2>推荐</h2>
<h2>{ topBanner.length }</h2>
</div>
)
};
const mapStateToProps = state => {
return {
topBanner: state.recommend.topBanners
}
}
const mapDispatchToProps = dispatch => {
return {
getTopBanner() {
// 这里派发这个函数
dispatch(getTopBannerAction())
}
}
}
// 将组件导出
export default connect(mapStateToProps, mapDispatchToDispatch)(memo(Recommend));
2.2 actionCreators文件
// 常量
import { CHANGE_TOP_BANNER } from "./constants";
import { getTopBanner } from "@/service/recommend";
// 改变状态的action
const changeBannerAction = banner => {
return {
type: CHANGE_TOP_BANNER,
banner
}
}
// 组件派发的函数 使用函数的形式 可以传递某些参数进来
const getTopBannerAction = () => {
return dispatch => {
// 发送网络请求
getTopBanner().then(res => {
const banner = res.banners;
// 在这里可以dispatch派发action 调用reducer函数来更改状态
dispatch(changeBannerAction(banner))
})
}
}
export { getTopBannerAction };
2.3 子reducer文件
// 常量
import { CHANGE_TOP_BANNER } from "./constants";
// 初始化的值
const initialState = {
topBanners: []
}
function reducer(state = initialState, action) {
switch(action.type) {
case CHANGE_TOP_BANNER:
return {...state, topBanners: action.banner}
default:
return state;
}
}
// 将reducer函数进行到处
export default reducer;
3、在react-redux中使用hooks
// 引入组件中的hooks
import React, { memo, useEffect } from 'react';
// 引入react-redux中的hooks
import { useDispatch, useSelector, shallowEqual } from "react-redux";
// 引入派发的函数
import { getTopBannerAction } from "./store/actionCreateors";
function Recommend() {
// 在业务组件中使用hook来获 我们需要的状态数据
const recommend = useSelector(state => {
return {
topBanners: state.recommend.topBanners
}
}, shallowEqual);
// 获取banner中的数据 直接进行解构与赋值
const { topBanners } = recommend;
// 使用hook来获取dispatch
const dispatch = useDispatch()
// 在hook中发送网络请求
useEffect(() => {
// 直接派发action
dispatch(getTopBannerAction())
}, [dispatch])
return (
<div>
<h2>推荐</h2>
<h2>{ topBanners.length }</h2>
</div>
)
};
// 将组件导出
export default memo(Recommend);
// 需要注意的是 这两个hooks是从react-redux中导入的
import { useSelector, useDispatch, shallowEqual } from "react-redux";
// react-redux中hooks的使用总结
// 不再使用connect函数了
// 直接使用const state = useSelector(() => {}, shallowEqual) 来代替mapStateToProps
// 直接使用const dispatch = useDispatch() 来代替mapDispatchToDispatch
const mapStateToProps = state => {
return {
topBanners: state.recommend.topBanners
}
}
// 上述使用hook来完成 得到的属性可以直接在组件中进行使用
const { topBanners } = useSelector(state => {
return {
topBanners: state.recommend.topBanners
}
}, shallowEqual)
// 说明 第一个参数是传入我们的state, 返回我们需要获取的数,这个返回的结果我们可以直接进行使用,也就是我们组件需要使用的数据。
const mapDispatchToProps = dispatch => {
return {
getTopBanner() {
// 直接派发action
dispatch(getTopBannerAction)
}
}
}
// 上述代码 使用useDispatch来改造
const dispatch = useDispatch();
// 可以直接派发action
dispatch(getTopBannerAction)
// 在hook中发送网络请求
useEffect(() => {
// 直接派发action
dispatch(getTopBannerAction())
}, [dispatch])
:::info react-redux中的hooks使用总结:使用非常的简洁
- 使用useSelector来代替原来的mapStateToProps。在使用useSelector的时候可以传入第二个参数shallowEqual来进行浅层比较,对代码进行性能优化。
- 使用useDispatch来代替原理的mapDispatchToprops。 :::
3.1 useSelector hook的使用
// redux中的两个非常重要的hook About组件
import React from 'react';
import { useEffect } from 'react';
import { useSelector, useDispatch } from "react-redux";
import {
incrementAction,
addNumberAction,
getSyncHomeData
} from "../../store/actionCreators";
function About(props) {
// 使用useSelector来代替mapStateToProps的功能
const count = useSelector(state => state.count)
// 使用useDispatch hook来代替mapStateToDispatch
const dispatch = useDispatch();
function increment() {
dispatch(incrementAction());
}
function incrementNumber() {
dispatch(addNumberAction(10));
}
// 获取异步数据
useEffect(() => {
// 派发action
dispatch(getSyncHomeData);
}, [dispatch])
return (
<div>
<h2>About组件4--{count}</h2>
<button onClick={increment}>+1</button>
<button onClick={incrementNumber}>+10</button>
</div>
)
}
export default About;
3.2 useDispatch hook的详细使用
// Home组件
import React from 'react';
import { useSelector, useDispatch } from "react-redux";
import {
decrementAction,
subNumberAction
} from "../../store/actionCreators"
function Home() {
// 使用useSelector来代替mapStateToProps
const state = useSelector(state => {
return {
count: state.count,
banner: state.banner,
recommend: state.recommend
}
})
// 使用useDispatch hook函数来代替mapStateToDispatch
const dispatch = useDispatch();
function decrement() {
dispatch(decrementAction())
}
function decrementNumber() {
dispatch(subNumberAction(10))
}
return (
<div>
<h2>Home组件4--{state.count}</h2>
<button onClick={decrement}>-1</button>
<button onClick={decrementNumber}>-10</button>
<h2>轮播数据</h2>
<ul>
{
state.banner.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
<h2>推荐数据</h2>
<ul>
{
state.recommend.map(item => {
return <li key={item.acm}>{item.title}</li>
})
}
</ul>
</div>
)
}
export default Home;