Pull上拉加载下拉刷新 - 图1

Pull 上拉加载下拉刷新

基本用法

  1. import { Pull, Cell } from 'zarm';
  2. const REFRESH_STATE = {
  3. normal: 0, // 普通
  4. pull: 1, // 下拉刷新(未满足刷新条件)
  5. drop: 2, // 释放立即刷新(满足刷新条件)
  6. loading: 3, // 加载中
  7. success: 4, // 加载成功
  8. failure: 5, // 加载失败
  9. };
  10. const LOAD_STATE = {
  11. normal: 0, // 普通
  12. abort: 1, // 中止
  13. loading: 2, // 加载中
  14. success: 3, // 加载成功
  15. failure: 4, // 加载失败
  16. complete: 5, // 加载完成(无新数据)
  17. };
  18. const getRandomNum = (min, max) => {
  19. const Range = max - min;
  20. const Rand = Math.random();
  21. return (min + Math.round(Rand * Range));
  22. }
  23. class Demo extends React.Component {
  24. mounted = true;
  25. state = {
  26. refreshing: REFRESH_STATE.normal,
  27. loading: LOAD_STATE.normal,
  28. dataSource: [],
  29. };
  30. componentDidMount() {
  31. this.appendData(20);
  32. }
  33. componentWillUnmount() {
  34. this.mounted = false;
  35. }
  36. // 模拟请求数据
  37. refreshData = () => {
  38. this.setState({ refreshing: REFRESH_STATE.loading });
  39. setTimeout(() => {
  40. if (!this.mounted) return;
  41. this.appendData(20, []);
  42. this.setState({
  43. refreshing: REFRESH_STATE.success,
  44. });
  45. }, 2000);
  46. }
  47. // 模拟加载更多数据
  48. loadData = () => {
  49. this.setState({ loading: LOAD_STATE.loading });
  50. setTimeout(() => {
  51. if (!this.mounted) return;
  52. const randomNum = getRandomNum(0, 5);
  53. const { dataSource } = this.state;
  54. let loading = LOAD_STATE.success;
  55. console.log(`状态: ${randomNum === 0 ? '失败' : (randomNum === 1 ? '完成' : '成功')}`);
  56. if (randomNum === 0) {
  57. loading = LOAD_STATE.failure;
  58. } else if (randomNum === 1) {
  59. loading = LOAD_STATE.complete;
  60. } else {
  61. this.appendData(20);
  62. }
  63. this.setState({ loading });
  64. }, 2000);
  65. }
  66. appendData(length, dataSource) {
  67. dataSource = dataSource || this.state.dataSource;
  68. const startIndex = dataSource.length;
  69. for (let i = startIndex; i < startIndex + length; i++) {
  70. dataSource.push(<Cell key={+i}>第 {i + 1} 行</Cell>);
  71. }
  72. this.setState({ dataSource });
  73. }
  74. render() {
  75. const { refreshing, loading, dataSource } = this.state;
  76. return (
  77. <Pull
  78. refresh={{
  79. state: refreshing,
  80. handler: this.refreshData,
  81. // render: (refreshState, percent) => {
  82. // const cls = 'custom-control';
  83. // switch (refreshState) {
  84. // case REFRESH_STATE.pull:
  85. // return (
  86. // <div className={cls}>
  87. // <ActivityIndicator loading={false} percent={percent} />
  88. // <span>下拉刷新</span>
  89. // </div>
  90. // );
  91. // case REFRESH_STATE.drop:
  92. // return (
  93. // <div className={cls}>
  94. // <ActivityIndicator loading={false} percent={100} />
  95. // <span>释放立即刷新</span>
  96. // </div>
  97. // );
  98. // case REFRESH_STATE.loading:
  99. // return (
  100. // <div className={cls}>
  101. // <ActivityIndicator type="spinner" />
  102. // <span>加载中</span>
  103. // </div>
  104. // );
  105. // case REFRESH_STATE.success:
  106. // return (
  107. // <div className={cls}>
  108. // <Icon type="right-round" theme="success" />
  109. // <span>加载成功</span>
  110. // </div>
  111. // );
  112. // case REFRESH_STATE.failure:
  113. // return (
  114. // <div className={cls}>
  115. // <Icon type="wrong-round" theme="danger" />
  116. // <span>加载失败</span>
  117. // </div>
  118. // );
  119. // default:
  120. // }
  121. // },
  122. }}
  123. load={{
  124. state: loading,
  125. distance: 200,
  126. handler: this.loadData,
  127. // render: (loadState) => {
  128. // const cls = 'custom-control';
  129. // switch (loadState) {
  130. // case LOAD_STATE.loading:
  131. // return <div className={cls}><ActivityIndicator type="spinner" /></div>;
  132. // case LOAD_STATE.failure:
  133. // return <div className={cls}>加载失败</div>;
  134. // case LOAD_STATE.complete:
  135. // return <div className={cls}>我是有底线的</div>;
  136. // }
  137. // },
  138. }}
  139. >
  140. {dataSource}
  141. </Pull>
  142. )
  143. }
  144. }
  145. ReactDOM.render(<Demo />, mountNode);

API

属性类型默认值说明
refreshAction-下拉刷新的参数配置
loadAction-上拉加载的参数配置
animationDurationnumber400动画执行时间,单位:毫秒
stayTimenumber1000加载成功停留时间

Action 类型定义

属性类型默认值说明
stateREFRESH_STATE | LOAD_STATE0状态枚举
startDistancenumber20下拉时的助跑距离,单位:px
distancenumber50触发距离阀值,单位:px
render(refreshState: REFRESH_STATE | LOAD_STATE, percent: number) => ReactNode-各状态渲染的回调函数
handler() => void-达到阀值后释放触发的回调函数

REFRESH_STATE 枚举定义

枚举值说明
normal普通状态
pull下拉状态(未满足刷新条件)
drop释放立即刷新(满足刷新条件)
loading加载中
success加载成功
failure加载失败

LOAD_STATE 枚举定义

枚举值说明
normal普通状态
abort终止状态
loading加载中
success加载成功
failure加载失败
complete加载完成