React-Redux结合Semantic-UI分页时如何将分页URL传入fetchProducts函数
分页组件与Redux请求链路打通方案
现有开发场景
- 技术栈:基于React实现分页组件,用Redux做全局状态管理,分页交互层用Semantic-UI的Pagination组件
- 现有代码结构:在action.jsx中同时定义了Paginator类组件、Redux异步拉取商品的
fetchProducts函数、分页切换的handlePage回调 - 核心卡点:
handlePage函数目前仅在Paginator组件内部运行,生成的带页码的请求url无法传递给外层的fetchProducts函数,导致点击分页时无法自动拉取对应页的商品数据
现存代码的可优化问题
handlePage中直接给未声明的paginationUrl全局变量赋值,存在状态污染风险,也没有把生成的url对接给Redux的action触发逻辑- Paginator组件没有接入Redux store,无法直接调用dispatch触发异步请求
- 组件挂载时单独用axios拉取分页元信息,和Redux管理的商品数据流程脱节,存在重复请求
- 分页切换时没有自动触发数据拉取的逻辑,点击页码后仅生成了url,没有后续动作
分步实现方案
1. 改造fetchProducts函数,支持接收请求地址入参
把原本硬编码的请求地址改成入参传入的形式,同时补全跨域认证参数,保持和原有登录逻辑一致:
export function fetchProducts(requestUrl) { return (dispatch) => { dispatch(fetchProductsRequest()) axios .get(requestUrl, { withCredentials: true }) .then(response => { const products = response.data.products // 拉取商品数据的同时,把分页元信息(当前页码、总页数)同步存入store,替代组件内部的本地state dispatch(fetchProductsSuccess( products, response.data.page, response.data.pages )) }) .catch(error => { dispatch(fetchProductsFailure(error.message)) }) } }
注意:原来代码里初始请求带了withCredentials: true,改造后的fetch请求必须保留这个参数,否则会丢失登录态导致接口鉴权失败
2. 给Paginator组件接入Redux,打通handlePage的触发链路
用react-redux的connect方法把组件和store关联,让组件可以拿到dispatch方法,把分页切换和请求触发的链路接上:
- 把原来组件本地维护的
page、pages状态,改成从Redux store中读取,保证全局状态一致 - 改造
handlePage逻辑:生成对应页码的请求url后,直接调用dispatch触发fetchProducts,把url作为参数传进去
改造后的核心逻辑示例:
// 绑定handlePage的上下文,避免回调触发时this指向错误 handlePage = (activePage) => { const paginationUrl = `/api/v1/products/index/?page=${activePage}`; // 直接把生成的url作为参数传给fetchProducts,完成链路传递 this.props.dispatch(fetchProducts(paginationUrl)); }
- 调整组件渲染部分的参数,把分页组件的数据源改成从store读取:
render() { return( <Pagination onPageChange={this.handlePage} size='mini' siblingRange="6" defaultActivePage={this.props.currentPage} // 从store读取当前页码 totalPages={this.props.totalPages} // 从store读取总页数 /> ) }
3. 补全初始化流程,减少重复请求
原来组件挂载时单独发请求拉取分页信息的逻辑,可以完全合并到初始的fetchProducts调用中:
- 组件首次加载时,主动触发一次无页码参数的请求:
fetchProducts('/api/v1/products/index'),一次性拉取第一页的商品数据+对应的分页元信息 - 删掉原来componentDidMount里单独拉分页信息的axios请求,避免重复调用接口
落地注意事项
- 不要把分页url存在全局变量里,每次切换页码时直接把url作为参数传给
fetchProducts即可,避免多页签、多组件场景下的状态污染 - Semantic-UI的Pagination组件的
onPageChange回调,默认会把用户点击的页码值作为第一个参数返回,刚好匹配handlePage的入参格式,不需要额外做参数适配 - Reducer层要同步增加对
fetchProductsSuccessaction的处理,把存进来的当前页码、总页数同步到store中,保证分页组件的显示状态和实际数据状态一致
内容的提问来源于stack exchange,提问作者Ashkan Ebtekari
相关产品推荐
相关产品推荐

