有好几个月没有接触react了,最近突然发现react项目方法 很流行用typescript方法来写,我就……,做前端太难了,技术一个接一个。
最近研究的是 关于 redux封装一个 table请求函数 还有用hook封装table请求方法这二者有啥不同。
首先先分析要实现的事情
视图层
一个table视图 需要传进去 pagesize,pagenum, total, data, loading 这些最基本的数据,
获取这些数据 要基于fetch请求
1、使用dva redux封装的请求插件 代码如下
import { request, postData } from '../util/request'
export default {
namespace: 'poemTable',
state: {
data: [],
pageNum: 1,
pageSize: 10,
total: 0,
loading: false
},
effects: {
*queryInitPoems(_, sageEffects) {
const { payload, callback} = _;
const { call, put } = sageEffects;
const { url, params} = payload;
let { pageSize, pageNum } = params;
yield put({ type: 'setLoad', payload: true});
yield put({ type: 'setPageInit',
payload: { pageSize, pageNum }
});
const res = yield call(postData, url, params);
yield put({ type: 'getList', payload: res});
yield put({ type: 'setLoad', payload: false});
if (callback) {
callback(res);
};
}
},
reducers: {
getList(state, { payload: resData }) {
return {
data: resData.data.list || [],
total: resData.data.count
};
},
setLoad(state, { payload: loadstate}) {
return {
...state,
loading: loadstate
}
},
setPageInit(state, { payload: { pageSize, pageNum }}) {
let nextpageSize = pageSize || state.pageSize;
let nextpageNum = pageSize || state.pageNum;
return {
...state,
pageSize: nextpageSize,
pageNum: nextpageNum
}
},
},
}
从上图可看 定义了初始化state数据 还有各种改变状态的方法 比如setLoad(设置加载) getList(获取列表)setPageInit(设置分页页码)
对应的react组件
// 诗歌列表
import React, { Component } from 'react';
import { Table, Tag, Space } from 'antd';
import { connect } from 'dva';
const namespace = 'poemTable';
const mapStateToProps = (state) => {
const poemList = state[namespace].data || [];
return Object.assign({}, state[namespace], {
poemList
})
};
const mapDispatchToProps = (dispatch) => {
return {
onDidMount: (obj) => {
obj = obj || {}
dispatch({
type: `${namespace}/queryInitPoems`,
payload: {
url: '/api/listpoem',
params: Object.assign({}, obj)
}
});
}
};
};
const columns = [
{
title: '标题',
dataIndex: 'title',
key: '_id',
},
{
title: '书籍',
dataIndex: 'book',
key: 'book',
},
{
title: '作者',
dataIndex: 'auther',
key: 'auther',
},
];
@connect(mapStateToProps, mapDispatchToProps)
export default class poemTablePage extends Component {
constructor(props) {
super(props);
this.state = {
}
}
componentDidMount() {
this.props.onDidMount({
pageNum: 1,
pageSize: 10,
});
}
render() {
let paginationSet = {
pageSize: this.props.pageSize,
current: this.props.pageNum,
total: this.props.total,
pageSizeOptions: [10, 20, 50, 100],
onChange: (page, pageSize) => {
console.log(page, pageSize);
this.props.onDidMount({
pageNum: page,
pageSize: pageSize,
});
}
}
console.log(paginationSet)
return (
<div>
<Table
loading={this.props.loading}
dataSource={this.props.poemList}
columns={columns}
rowKey={(record) => record._id}
pagination={paginationSet}
/>
</div>
)
}
}
通过mapStateToProps, mapDispatchToProps 方法注入到组件props中,table组件中直接去引用redux state中的数据和方法,这样就实现了 数据和代码的良好拆分。
2、使用hook封装的table函数
// 封装hook插件
import {useEffect, useState, useCallback} from 'react';
import { postData } from '../util/request'
let defaultTableSet = {
data: [],
pageNum: 1,
pageSize: 10,
total: 0,
}
export function useTableHook(url, params) {
const [loading, setLoading] = useState(false)
const [data, setData] = useState(defaultTableSet);
const loadData = async (inputparams) => {
setLoading(true);
if(inputparams) {
params = inputparams
}
let { pageNum, pageSize } = params;
let request = await postData(url, params);
setLoading(false);
setData(prevState => {
return {...prevState, ...{
data: request.data.list || [],
total: request.data.count,
pageNum,
pageSize
}};
});
}
useEffect(() => {
loadData()
}, [])
return {
loadData,
...data,
loading
}
}
和 redux类似的思想, 有默认状态,和改变状态的方法 setData, setLoading, 获取数据函数 loaddata
对应的hook函数组件
// 使用hook方法 加载诗歌列表
import { Table, Tag, Space } from 'antd';
import { useTableHook } from '../hook/tablehook'
const columns = [
{
title: '标题',
dataIndex: 'title',
key: '_id',
},
{
title: '书籍',
dataIndex: 'book',
key: 'book',
},
{
title: '作者',
dataIndex: 'auther',
key: 'auther',
},
];
const poemTableHook = () => {
const gethookdata = useTableHook('/api/listpoem', {
pageNum: 1,
pageSize: 10,
})
// let poemList = gethookdata.data;
let paginationSet = {
pageSize: gethookdata.pageSize,
current: gethookdata.pageNum,
total: gethookdata.total,
pageSizeOptions: [10, 20, 50, 100],
onChange: (page, pageSize) => {
console.log(page, pageSize);
gethookdata.loadData({
pageNum: page,
pageSize: pageSize,
});
}
}
return (
<div>
<Table
loading={gethookdata.loading}
dataSource={gethookdata.data}
columns={columns}
rowKey={(record) => record._id}
pagination={paginationSet}
/>
</div>
)
}
export default poemTableHook
通过useState, useEffect方法 就可以 实现将数据和方法 放到组件中。相比较redux模型,hook方法更简介,直观。
以上就是对两个方法的对比和使用。