一、介绍
列表页是常用的功能,从后端获取列表数据,刷新到页面上。开发列表页需要考虑以下技术要点:1.如何翻页;2.如何进行内容搜索;3.如何缓存数据;4.何时进行页面刷新。
二、使用教程
1.redux
actions.js
export function fetchList(page = 1, keyword = "", pageSize = 3) {
// action
return dispatch => {
// 开始加载列表
dispatch({
type: "FETCH_LIST_BEGIN",
});
const promise = new Promise((resolve, reject) => {
const doRequest = axios.get(
`https://reqres.in/api/users?page=${page}&per_page=${pageSize}&q=${keyword}`,
);
doRequest.then(
res => {
// 加载列表成功
dispatch({
type: "FETCH_LIST_SUCCESS",
data: {
items: res.data.data,
page,
pageSize,
total: res.data.total,
},
});
resolve(res);
},
err => {
// 加载列表失败
dispatch({
type: "FETCH_LIST_ERROR",
data: { error: err },
});
reject(err);
},
);
});
return promise;
};
}
reducer.js
const initialState = {
items: [],
page: 1,
pageSize: 3,
total: 0,
fetchListPending: false,
fetchListError: null,
listNeedReload: false,
};
// reducer
export default (state = initialState, action) => {
switch (action.type) {
case "FETCH_LIST_BEGIN":
return {
...state,
fetchListPending: true,
fetchListError: null,
};
case "FETCH_LIST_SUCCESS": {
const byId = {};
const items = [];
action.data.items.forEach(item => {
items.push(item);
});
return {
...state,
items,
page: action.data.page,
pageSize: action.data.pageSize,
total: action.data.total,
fetchListPending: false,
fetchListError: null,
};
}
case "FETCH_LIST_ERROR":
return {
...state,
fetchListPending: false,
fetchListError: action.data,
};
break;
default:
break;
}
return state;
};
2.demo
export const ListPage = () =>{
const [search, setSearch] = useState('');
const [state, dispatch] = useReducer(reducer, initialState);
const {page, total, pageSize,keyword, items, fetchListPending} = state
const getColumns = () => {
return [
{
title: "First Name",
dataIndex: "first_name",
render: (firstName, rec) => (
<Link to={`/user/${rec.id}`}>{firstName}</Link>
),
}
];
}
handleSearch = keyword => {
fetchList(page, pageSize, keyword)(dispatch);
};
const dataSourceSelector = createSelector(getItems, getById, (items) => {
console.log("reselect: get data source");
if (!items) return [];
return items
});
return (<>
<div>
<h2>User List</h2>
<Input.Search
value={search}
onChange={e => setSearch( e.target.value )}
style={{ width: "200px" }}
onSearch=handleSearch}
/>
<Table
dataSource={dataSourceSelector(state)}
columns={getColumns()}
style={{ width: "400px" }}
rowKey="id"
loading={fetchListPending}
pagination={false}
/>
<Pagination
current={page}
total={total}
pageSize={pageSize}
/>
</div>
</>);
}