---
title: WKListContainer 列表容器
group:
  title: 展示组件
  path: /show/
---

## 何时使用

- 需要展示列表数据的情况，如商品列表、订单列表等
- WKListContainer 会自动维护上拉加载更多，下拉刷新，首次请求数据
- WKListContainer 需要实现 onFetch 方法，需要提供列表请求参数

## 基本使用

```tsx
/**
 * title: 基本使用
 * desc: 基本使用方法
 */
import React from 'react';
import PageWrapper from '../PageWrapper';
import { WKListContainer, View, WKDivider, WKImage, WKEmptyProps } from '@wakeapp/components';
interface GoodProps {
  id: any;
  appId: any;
  storeName: any;
  storeNo: any;
  activityType: any;
  itemNo: any;
  itemCreateTime: any;
  name: any;
  categoryName: any;
  isShelf: any;
  salePrice: any;
  labelPrice: any;
  categoryId: any;
  thumbnail: any;
  salesVolume: any;
  cashCommissionRate: any;
  cashCommissionAmount: any;
  sourceType: any;
  stock: any;
  copyItemNo: any;
  amountMode: any;
}

interface IFilter {
  categoryId: number;
  storeNo: string;
}

const totalCount = 40;
const pageSize = 20;

export default () => {
  const data: GoodProps = {
    id: 72,
    appId: 1132,
    storeName: 'w零食自营店',
    storeNo: '202112160001',
    activityType: 0,
    itemNo: '202112160011',
    itemCreateTime: '2021-12-17 17:04:10',
    name: '苹果',
    categoryName: '苹果',
    isShelf: 1,
    salePrice: 200,
    labelPrice: 2000,
    categoryId: 130,
    thumbnail: 'https://dxcc.octohbay.net/test-material-1259575047/332e2c6727c9435cb337853befdd2523.png',
    salesVolume: 1,
    cashCommissionRate: 80,
    cashCommissionAmount: 160,
    sourceType: 1,
    stock: 1,
    copyItemNo: '202112160011',
    amountMode: false,
  };

  const filterParms: IFilter = {
    categoryId: 0,
    storeNo: '0',
  };

  const onFetch = (params: { filter?: IFilter; offset: number; pageNo: number; pageSize: number }) => {
    console.log('-> params', params);
    return Promise.resolve({
      data: Array<GoodProps>(
        totalCount - params.offset > params.pageSize ? params.pageNo * params.pageSize : totalCount - params.offset
      ).fill(data),
      totalCount,
      pageSize,
      pageNo: params.pageNo++,
      success: true,
      __raw__: {} as any,
    });
  };
  const headerView = <View style={{ backgroundColor: 'orange', width: '100vw', height: '50px' }}>头部</View>;
  const footerView = (
    <View style={{ backgroundColor: 'orange', width: '100vw', height: '50px', position: 'absolute' }}>尾部</View>
  );
  const loadingView = (hasMores: boolean) => {
    return <WKDivider tip={hasMores ? '加载中....' : '这就是我的底线了'} />;
  };
  const emptyProps: WKEmptyProps = {
    style: {
      top: '50%',
      left: '50%',
      position: 'absolute',
      transform: 'translate(-50%, -50%)',
    },
    desc: '暂无数据',
  };

  const container = {
    position: 'relative',
    width: '100%',
    height: '100%',
  };
  const good = {
    display: 'flex',
    flexDirection: 'column',
  };
  const goodContent = {
    display: 'flex',
    flexDirection: 'row',
  };
  const img = {
    margin: '20px',
    width: '180px',
    height: '180px',
  };
  const content = {
    display: 'flex',
    flexDirection: 'column',
  };
  const marginTop = {
    marginTop: '5px',
  };

  return (
    <PageWrapper title="基本使用">
      <View style={container}>
        <WKListContainer
          mode="scrollView"
          pageSize={pageSize}
          filter={filterParms}
          style={{ height: '100vh' }}
          emptyProps={emptyProps}
          footerStyle={{ position: 'absolute', height: '50px', bottom: 0 }}
          virtualListStyle={{ marginTop: '50px', marginBottom: '50px', height: 'calc(100% - 100px)' }}
          headerStyle={{ position: 'absolute', height: '50px', top: 0 }}
          onFetch={onFetch}
          renderItem={(item, index) => {
            return (
              <View style={good} key={item.id + index}>
                <View style={goodContent}>
                  <WKImage style={img} width="50px" height="50px" src={item.thumbnail} />
                  <View style={content}>
                    <View style={marginTop}>{item.name + index}</View>
                    <View style={marginTop}>{item.storeName + index}</View>
                    <View style={marginTop}>￥{item.salePrice}</View>
                  </View>
                </View>
                <WKDivider style={{ margin: '0 20px' }} />
              </View>
            );
          }}
          header={headerView}
          footer={footerView}
          renderLoading={loadingView}
        />
      </View>
    </PageWrapper>
  );
};
```

## 暂无数据

```tsx
import React from 'react';
import PageWrapper from '../PageWrapper';
import { WKListContainer, View, WKDivider, WKImage, WKEmptyProps } from '@wakeapp/components';
interface GoodProps {
  id: any;
  appId: any;
  storeName: any;
  storeNo: any;
  activityType: any;
  itemNo: any;
  itemCreateTime: any;
  name: any;
  categoryName: any;
  isShelf: any;
  salePrice: any;
  labelPrice: any;
  categoryId: any;
  thumbnail: any;
  salesVolume: any;
  cashCommissionRate: any;
  cashCommissionAmount: any;
  sourceType: any;
  stock: any;
  copyItemNo: any;
  amountMode: any;
}

interface IFilter {
  categoryId: number;
  storeNo: string;
}

const totalCount = 0;
const pageSize = 20;

export default () => {
  const data: GoodProps = {
    id: 72,
    appId: 1132,
    storeName: 'w零食自营店',
    storeNo: '202112160001',
    activityType: 0,
    itemNo: '202112160011',
    itemCreateTime: '2021-12-17 17:04:10',
    name: '苹果',
    categoryName: '苹果',
    isShelf: 1,
    salePrice: 200,
    labelPrice: 2000,
    categoryId: 130,
    thumbnail: 'https://dxcc.octohbay.net/test-material-1259575047/332e2c6727c9435cb337853befdd2523.png',
    salesVolume: 1,
    cashCommissionRate: 80,
    cashCommissionAmount: 160,
    sourceType: 1,
    stock: 1,
    copyItemNo: '202112160011',
    amountMode: false,
  };

  const filterParms: IFilter = {
    categoryId: 0,
    storeNo: '0',
  };

  const onFetch = (params: { filter?: IFilter; offset: number; pageNo: number; pageSize: number }) => {
    console.log('-> params', params);
    return Promise.resolve({
      data: Array<GoodProps>(
        totalCount - params.offset > params.pageSize ? params.pageNo * params.pageSize : totalCount - params.offset
      ).fill(data),
      totalCount,
      pageSize,
      pageNo: params.pageNo++,
      success: true,
      __raw__: {} as any,
    });
  };
  const headerView = <View style={{ backgroundColor: 'orange', width: '100vw', height: '50px' }}>头部</View>;
  const footerView = (
    <View style={{ backgroundColor: 'orange', width: '100vw', height: '50px', position: 'absolute' }}>尾部</View>
  );
  const loadingView = (hasMores: boolean) => {
    return <WKDivider tip={hasMores ? '加载中....' : '这就是我的底线了'} />;
  };
  const emptyProps: WKEmptyProps = {
    style: {
      top: '50%',
      left: '50%',
      position: 'absolute',
      transform: 'translate(-50%, -50%)',
    },
    desc: '暂无数据',
  };

  const container = {
    position: 'relative',
    width: '100%',
    height: '100%',
  };
  const good = {
    display: 'flex',
    flexDirection: 'column',
  };
  const goodContent = {
    display: 'flex',
    flexDirection: 'row',
  };
  const img = {
    margin: '20px',
    width: '180px',
    height: '180px',
  };
  const content = {
    display: 'flex',
    flexDirection: 'column',
  };
  const marginTop = {
    marginTop: '5px',
  };

  return (
    <PageWrapper title="暂无数据">
      <View style={container}>
        <WKListContainer
          mode="scrollView"
          pageSize={pageSize}
          filter={filterParms}
          style={{ height: '100vh' }}
          emptyProps={emptyProps}
          footerStyle={{ position: 'absolute', height: '50px', bottom: 0 }}
          virtualListStyle={{ marginTop: '50px', marginBottom: '50px', height: 'calc(100% - 100px)' }}
          headerStyle={{ position: 'absolute', height: '50px', top: 0 }}
          onFetch={onFetch}
          renderItem={(item, index) => {
            return (
              <View style={good} key={item.id + index}>
                <View style={goodContent}>
                  <WKImage style={img} width="50px" height="50px" src={item.thumbnail} />
                  <View style={content}>
                    <View style={marginTop}>{item.name + index}</View>
                    <View style={marginTop}>{item.storeName + index}</View>
                    <View style={marginTop}>￥{item.salePrice}</View>
                  </View>
                </View>
                <WKDivider style={{ margin: '0 20px' }} />
              </View>
            );
          }}
          header={headerView}
          footer={footerView}
          renderLoading={loadingView}
        />
      </View>
    </PageWrapper>
  );
};
```

<API src='@wakeapp/components/WKListView/WKListContainer.d.ts'></API>

## WKEmptyProps

| Name      | Description    | Type                                                                   | Default         |
| --------- | -------------- | ---------------------------------------------------------------------- | --------------- |
| className | 类名           | `string`                                                               |                 |
| style     | 样式           | `React.CSSProperties`                                                  |                 |
| type      | 类型           | `'error' \| 'network' \| 'empty' \| 'default' \| 'search' \| 'custom'` | `default`       |
| url       | 自定义图标地址 | `string`                                                               | `./default.png` |
| desc      | 描述           | `React.CSSProperties`                                                  |                 |
| detail    | 详情           | `React.CSSProperties`                                                  |                 |
| retryText | 重试文本       | `React.CSSProperties`                                                  |                 |
| onRetry   | 点击触发重试   | `() => void`                                                           |                 |
