一、介绍

        列表页是常用的功能,从后端获取列表数据,刷新到页面上。开发列表页需要考虑以下技术要点: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>
        </>);
    
}
12-10 16:43