New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

antd-table-infinity

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

antd-table-infinity - npm Package Compare versions

Comparing version 1.1.2 to 1.1.3

3

es/InfinityTable/index.js

@@ -416,2 +416,3 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

forwardedRef: ref
})));
})));
export { InfinityTable };

@@ -278,3 +278,3 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

}
}, loading && loadingIndicator, ' '), domNode);
}, loading && loadingIndicator, " "), domNode);
}

@@ -583,3 +583,3 @@

loadingIndicator: loadingIndicator
}), !this.isInitial && pagination && ['top', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({
}), total && pagination && ['top', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({
showQuickJumper: true

@@ -601,3 +601,3 @@ }, pagination, {

className: `infinity-page-table ${rest.className ? rest.className : ''}`
})), !this.isInitial && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({
})), total && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && React.createElement(Pagination, _extends({
showQuickJumper: true

@@ -679,2 +679,3 @@ }, pagination, {

forwardedRef: ref
})));
})));
export { InfinityTable };

@@ -6,3 +6,3 @@ "use strict";

});
exports.default = void 0;
exports.InfinityTable = exports.default = void 0;

@@ -389,2 +389,3 @@ var _react = _interopRequireWildcard(require("react"));

exports.InfinityTable = InfinityTable;
InfinityTable.defaultProps = {

@@ -391,0 +392,0 @@ // loading 效果, A visual react component for Loading status

@@ -6,3 +6,3 @@ "use strict";

});
exports.default = void 0;
exports.InfinityTable = exports.default = void 0;

@@ -294,3 +294,3 @@ var _react = _interopRequireWildcard(require("react"));

}
}, loading && loadingIndicator, ' '), domNode);
}, loading && loadingIndicator, " "), domNode);
}

@@ -599,3 +599,3 @@

loadingIndicator: loadingIndicator
}), !this.isInitial && pagination && ['top', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({
}), total && pagination && ['top', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({
showQuickJumper: true

@@ -617,3 +617,3 @@ }, pagination, {

className: `infinity-page-table ${rest.className ? rest.className : ''}`
})), !this.isInitial && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({
})), total && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && _react.default.createElement(_antd.Pagination, _extends({
showQuickJumper: true

@@ -632,2 +632,3 @@ }, pagination, {

exports.InfinityTable = InfinityTable;
InfinityTable.defaultProps = {

@@ -634,0 +635,0 @@ // loading 效果, A visual react component for Loading status

{
"name": "antd-table-infinity",
"version": "1.1.2",
"version": "1.1.3",
"scripts": {

@@ -5,0 +5,0 @@ "storybook": "start-storybook -p 9001 -c .storybook",

@@ -106,2 +106,3 @@ 中文 | [English](./README_en.md)

<Table
rowKey='key' // 非常重要,请按你的数据列正确设置,否则滚动会出问题
className="custom-classname"

@@ -191,3 +192,3 @@ pagination={{

<Table
key="key"
rowKey='key' // 非常重要,请按你的数据列正确设置,否则滚动会出问题
loading={this.state.loading}

@@ -264,3 +265,3 @@ onFetch={this.handleFetch}

<Table
key="key"
rowKey='key' // 非常重要,请按你的数据列正确设置,否则滚动会出问题
loading={this.state.loading}

@@ -300,2 +301,4 @@ onFetch={this.handleFetch}

- `import 'antd-table-infinity/dist/index.css'`; 包含使用到的antd相关组件的所有css
3. rowKey='key' 非常重要,antd-table需要的每行数据的唯一键值,否则滚动翻页会出问题,实在没有,请用 uuid 库创建 参考:[https://ant.design/components/table-cn/#%E6%B3%A8%E6%84%8F](https://ant.design/components/table-cn/#%E6%B3%A8%E6%84%8F)


@@ -302,0 +305,0 @@ ### 已发现问题

@@ -404,1 +404,3 @@ import React, { PureComponent, Fragment } from 'react';

));
export { InfinityTable }

@@ -1,709 +0,594 @@

import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
import {
element,
string,
bool,
number,
array,
object,
func,
oneOfType,
oneOf,
shape,
} from 'prop-types';
import { Table, Spin, Pagination } from 'antd';
import throttle from 'lodash.throttle';
import React, { Component, Fragment } from 'react'
import ReactDOM from 'react-dom'
import { element, string, bool, number, array, object, func, oneOfType, oneOf, shape } from 'prop-types'
import { Table, Spin, Pagination } from 'antd'
import throttle from 'lodash.throttle'
const noop = () => {};
const noop = () => {}
const fetchDebounce = (() => {
const loading = [];
return ({ page, pageSize, onFetch }) => {
const now = Date.now();
if (!loading[page] || (loading[page] && now - loading[page] > 1000)) {
onFetch({ page, pageSize });
}
loading[page] = now;
};
})();
const loading = []
return ({ page, pageSize, onFetch }) => {
const now = Date.now()
if (!loading[page] || (loading[page] && now - loading[page] > 1000)) {
onFetch({ page, pageSize })
}
loading[page] = now
}
})()
function getCachePage({
step,
maxPage,
pageSize,
onFetch,
loading,
cacheData,
currentPage,
}) {
const pageBefore = currentPage - step;
const pageAfter = currentPage + step;
const cachePageDataBefore = cacheData[pageBefore];
const cachePageData = cacheData[currentPage];
const cachePageDataAfter = cacheData[pageAfter];
if (!loading) {
!cachePageData &&
currentPage > 0 &&
currentPage <= maxPage &&
fetchDebounce({ page: currentPage, pageSize, onFetch });
!cachePageDataBefore &&
pageBefore > 0 &&
pageBefore <= maxPage &&
fetchDebounce({ page: pageBefore, pageSize, onFetch });
!cachePageDataAfter &&
pageAfter > 0 &&
pageAfter <= maxPage &&
fetchDebounce({ page: pageAfter, pageSize, onFetch });
}
let lastOwnDataPage = currentPage;
if (cachePageDataAfter) {
lastOwnDataPage = pageAfter;
} else if (cachePageData) {
lastOwnDataPage = currentPage;
} else if (cachePageDataBefore) {
lastOwnDataPage = pageBefore;
}
function getCachePage({ step, maxPage, pageSize, onFetch, loading, cacheData, currentPage }) {
const pageBefore = currentPage - step
const pageAfter = currentPage + step
const cachePageDataBefore = cacheData[pageBefore]
const cachePageData = cacheData[currentPage]
const cachePageDataAfter = cacheData[pageAfter]
if (!loading) {
!cachePageData &&
currentPage > 0 &&
currentPage <= maxPage &&
fetchDebounce({ page: currentPage, pageSize, onFetch })
!cachePageDataBefore &&
pageBefore > 0 &&
pageBefore <= maxPage &&
fetchDebounce({ page: pageBefore, pageSize, onFetch })
!cachePageDataAfter &&
pageAfter > 0 &&
pageAfter <= maxPage &&
fetchDebounce({ page: pageAfter, pageSize, onFetch })
}
let lastOwnDataPage = currentPage
if (cachePageDataAfter) {
lastOwnDataPage = pageAfter
} else if (cachePageData) {
lastOwnDataPage = currentPage
} else if (cachePageDataBefore) {
lastOwnDataPage = pageBefore
}
return [
cachePageDataBefore || [],
cachePageData || [],
cachePageDataAfter || [],
lastOwnDataPage,
];
return [cachePageDataBefore || [], cachePageData || [], cachePageDataAfter || [], lastOwnDataPage]
}
const computeState = (
{
pageSize,
onFetch,
loading,
total,
bidirectionalCachePages: cachePages,
dataSource: [page, data],
},
{ maxPage, currentPage, cacheData, rowHeight },
{ pageSize, onFetch, loading, total, bidirectionalCachePages: cachePages, dataSource: [page, data] },
{ maxPage, currentPage, cacheData, rowHeight },
) => {
let bidirectionalCachePages = cachePages;
let newCacheData = cacheData;
let bidirectionalCachePages = cachePages
let newCacheData = cacheData
if (cachePages < 1) {
bidirectionalCachePages = 1;
}
if (bidirectionalCachePages * 2 + 1 < maxPage) {
let startPage = currentPage - bidirectionalCachePages;
startPage = startPage < 1 ? 1 : startPage;
if (cachePages < 1) {
bidirectionalCachePages = 1
}
if (bidirectionalCachePages * 2 + 1 < maxPage) {
let startPage = currentPage - bidirectionalCachePages
startPage = startPage < 1 ? 1 : startPage
let endPage = currentPage + bidirectionalCachePages;
endPage = endPage > maxPage ? maxPage : endPage;
let endPage = currentPage + bidirectionalCachePages
endPage = endPage > maxPage ? maxPage : endPage
cacheData[page] = data; // eslint-disable-line
newCacheData = Array.from({ length: maxPage });
cacheData[page] = data // eslint-disable-line
newCacheData = Array.from({ length: maxPage })
Array.prototype.splice.apply(
newCacheData,
[startPage, endPage - startPage + 1].concat(
cacheData.slice(startPage, endPage + 1),
),
);
}
newCacheData[page] = data;
Array.prototype.splice.apply(
newCacheData,
[startPage, endPage - startPage + 1].concat(cacheData.slice(startPage, endPage + 1)),
)
}
newCacheData[page] = data
const [
cachePageDataBefore,
cachePageData,
cachePageDataAfter,
lastOwnDataPage,
] = getCachePage({
step: 1,
maxPage,
pageSize,
onFetch,
loading,
cacheData: newCacheData,
currentPage,
});
const [cachePageDataBefore, cachePageData, cachePageDataAfter, lastOwnDataPage] = getCachePage({
step: 1,
maxPage,
pageSize,
onFetch,
loading,
cacheData: newCacheData,
currentPage,
})
const upperHeight = Math.round(
(currentPage - 1 - (cachePageDataBefore.length ? 1 : 0)) *
pageSize *
rowHeight,
);
const upperHeight = Math.round((currentPage - 1 - (cachePageDataBefore.length ? 1 : 0)) * pageSize * rowHeight)
const underHeight = Math.round(
// 已经是最后一页,直接返回0,否则如果有零头total % pageSize,需要加上不满一个page的零头lastOwnDataPageLength,但需要少加一个整页pageSize
maxPage === lastOwnDataPage
? 0
: ((maxPage - lastOwnDataPage) * pageSize + (total % pageSize)) *
rowHeight,
);
const dataSource = cachePageDataBefore
.concat(cachePageData)
.concat(cachePageDataAfter);
const underHeight = Math.round(
// 已经是最后一页,直接返回0,否则如果有零头total % pageSize,需要加上不满一个page的零头lastOwnDataPageLength,但需要少加一个整页pageSize
maxPage === lastOwnDataPage ? 0 : ((maxPage - lastOwnDataPage) * pageSize + (total % pageSize)) * rowHeight,
)
const dataSource = cachePageDataBefore.concat(cachePageData).concat(cachePageDataAfter)
return {
hasCacheBefore: !!cachePageDataBefore.length,
hasCache: !!cachePageData.length,
hasCacheAfter: !!cachePageDataAfter.length,
cacheData: newCacheData,
dataSource,
underHeight,
upperHeight,
};
};
return {
hasCacheBefore: !!cachePageDataBefore.length,
hasCache: !!cachePageData.length,
hasCacheAfter: !!cachePageDataAfter.length,
cacheData: newCacheData,
dataSource,
underHeight,
upperHeight,
}
}
/* eslint-disable react/no-redundant-should-component-update */
class InfinityTable extends Component {
static PlaceHolder({ height, domNode, loading, loadingIndicator }) {
return (
domNode &&
ReactDOM.createPortal(
<div style={{ height: `${height}px` }}>
{loading && loadingIndicator}{' '}
</div>,
domNode,
)
);
}
static LoadingPlaceHolder({ domNode, loading, loadingIndicator }) {
return (
domNode &&
ReactDOM.createPortal(loading ? loadingIndicator : <div />, domNode)
);
}
state = {
scrollTop: 0, // 滚动条位置
dataSource: [], // DOM上显示的数据
rowHeight: 0, // 每行的实际高度
cacheData: [], // 缓存的数据集大小
currentPage: 1, // 当前页位置
underHeight: 0, // 下撑高
upperHeight: 0, // 上撑高
};
static getDerivedStateFromProps(props, prevState) {
return computeState(props, prevState);
}
static PlaceHolder({ height, domNode, loading, loadingIndicator }) {
return (
domNode &&
ReactDOM.createPortal(<div style={{ height: `${height}px` }}>{loading && loadingIndicator} </div>, domNode)
)
}
static LoadingPlaceHolder({ domNode, loading, loadingIndicator }) {
return domNode && ReactDOM.createPortal(loading ? loadingIndicator : <div />, domNode)
}
state = {
scrollTop: 0, // 滚动条位置
dataSource: [], // DOM上显示的数据
rowHeight: 0, // 每行的实际高度
cacheData: [], // 缓存的数据集大小
currentPage: 1, // 当前页位置
underHeight: 0, // 下撑高
upperHeight: 0, // 上撑高
}
static getDerivedStateFromProps(props, prevState) {
return computeState(props, prevState)
}
componentDidMount() {
/* eslint-disable */
this.refRoot = ReactDOM.findDOMNode(this);
this.refScroll = this.refRoot.getElementsByClassName('ant-table-body')[0];
this.refTable = this.refScroll.getElementsByTagName('tbody')[0];
/* eslint-enabled */
this.createUnderPlaceholder();
this.createUpperPlaceholder();
this.setStateWithThrottle = throttle(this.updateTable, 0);
this.props.onScroll &&
this.refScroll.addEventListener('scroll', this.props.onScroll);
componentDidMount() {
/* eslint-disable */
this.refRoot = ReactDOM.findDOMNode(this)
this.refScroll = this.refRoot.getElementsByClassName('ant-table-body')[0]
this.refTable = this.refScroll.getElementsByTagName('tbody')[0]
/* eslint-enabled */
this.createUnderPlaceholder()
this.createUpperPlaceholder()
this.setStateWithThrottle = throttle(this.updateTable, 0)
this.props.onScroll && this.refScroll.addEventListener('scroll', this.props.onScroll)
if (this.refScroll) {
this.io = new IntersectionObserver(
changes => {
const { debug } = this.props;
let shouldUpdate = true;
this.ioTargetState = changes.reduce((result, change) => {
const ret = { ...result };
switch (change.target) {
case this.refPageBoundaryBefore:
ret.refPageBoundaryBefore = change;
// Bug fix:
// 向下滚动的时候,如果边界第一行数据触发,不需要更新视图,因为上一页的最后一行已经触发了视图更新,
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码
if (
!this.isPaginationClick &&
changes.length === 1 &&
this.state.direction === 'down'
) {
shouldUpdate = false;
}
if (this.refScroll) {
this.io = new IntersectionObserver(
changes => {
const { debug } = this.props
let shouldUpdate = true
this.ioTargetState = changes.reduce((result, change) => {
const ret = { ...result }
switch (change.target) {
case this.refPageBoundaryBefore:
ret.refPageBoundaryBefore = change
// Bug fix:
// 向下滚动的时候,如果边界第一行数据触发,不需要更新视图,因为上一页的最后一行已经触发了视图更新,
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码
if (
!this.isPaginationClick &&
changes.length === 1 &&
this.state.direction === 'down'
) {
shouldUpdate = false
}
break;
case this.refPageBoundaryAfter:
ret.refPageBoundaryAfter = change;
// Bug fix:
// 向上滚动的时候,如果边界最后行数据触发,不需要更新视图,因为上一页的第一行已经触发了视图更新
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码
if (
!this.isPaginationClick &&
changes.length === 1 &&
this.state.direction === 'up'
) {
shouldUpdate = false;
}
break;
default: // console.log(change)
}
return ret;
}, this.ioTargetState);
break
case this.refPageBoundaryAfter:
ret.refPageBoundaryAfter = change
// Bug fix:
// 向上滚动的时候,如果边界最后行数据触发,不需要更新视图,因为上一页的第一行已经触发了视图更新
// 但是用户通过点击分页切换,而不是滚动的情况例外,因为此时需要更新页码
if (!this.isPaginationClick && changes.length === 1 && this.state.direction === 'up') {
shouldUpdate = false
}
break
default: // console.log(change)
}
return ret
}, this.ioTargetState)
this.isPaginationClick = false;
this.isPaginationClick = false
debug &&
console.log('shouldUpdate:IntersectionObserver', {
shouldUpdate,
changes,
});
debug &&
console.log('shouldUpdate:IntersectionObserver', {
shouldUpdate,
changes,
})
shouldUpdate && this.setStateWithThrottle();
},
{
root: this.refScroll,
threshold: [0, 1],
},
);
this.toggleObserver();
}
shouldUpdate && this.setStateWithThrottle()
},
{
root: this.refScroll,
threshold: [0, 1],
},
)
this.toggleObserver()
}
this.props.onFetch({ page: 1, pageSize: this.props.pageSize });
this.props.onFetch({ page: 1, pageSize: this.props.pageSize })
new Promise(reslove => {
this.initialReslove = reslove;
}).then(() => {
const {
pageSize,
pagination: { defaultCurrent = 1 },
} = this.props;
this.createLoadingPlaceholder(); // fullLoading
this.scrollToPage(defaultCurrent);
const visibleRowCount = Math.round(
this.refScroll.clientHeight / this.state.rowHeight,
);
this.isReady = true;
if (pageSize < visibleRowCount) {
console.warn(
`pagesize(${pageSize}) less than visible row count(${visibleRowCount}), maybe you set error!`,
);
}
});
}
shouldComponentUpdate(nextProps, nextState) {
const { pageSize, debug } = nextProps;
const {
maxPage,
currentPage,
dataSource,
direction,
rowHeight,
} = nextState;
let shouldUpdate = true;
new Promise(reslove => {
this.initialReslove = reslove
}).then(() => {
const {
pageSize,
pagination: { defaultCurrent = 1 },
} = this.props
this.createLoadingPlaceholder() // fullLoading
this.scrollToPage(defaultCurrent)
const visibleRowCount = Math.round(this.refScroll.clientHeight / this.state.rowHeight)
this.isReady = true
if (pageSize < visibleRowCount) {
console.warn(
`pagesize(${pageSize}) less than visible row count(${visibleRowCount}), maybe you set error!`,
)
}
})
}
shouldComponentUpdate(nextProps, nextState) {
const { pageSize, debug } = nextProps
const { maxPage, currentPage, dataSource, direction, rowHeight } = nextState
let shouldUpdate = true
// 有且仅有当前页上下边界同时触发时,表示更换边界,不需要更新
if (this.isPageBoundary) {
shouldUpdate = false;
this.isPageBoundary = false;
}
debug && console.log('shouldUpdate:updateBoundary', { shouldUpdate });
// 有且仅有当前页上下边界同时触发时,表示更换边界,不需要更新
if (this.isPageBoundary) {
shouldUpdate = false
this.isPageBoundary = false
}
debug && console.log('shouldUpdate:updateBoundary', { shouldUpdate })
if (shouldUpdate && !this.isInitial) {
let currentPageReal = currentPage;
if (shouldUpdate && !this.isInitial) {
let currentPageReal = currentPage
// 由于state中的currentPage延迟与真实的currentPage不一致,当出现这种情况时,强制updateTable()
currentPageReal =
Math.floor(this.refScroll.scrollTop / (pageSize * rowHeight)) + 1 || 1;
currentPageReal = currentPageReal > maxPage ? maxPage : currentPageReal;
if (currentPageReal !== currentPage) {
this.updateTable();
shouldUpdate = false;
}
// 由于state中的currentPage延迟与真实的currentPage不一致,当出现这种情况时,强制updateTable()
currentPageReal = Math.floor(this.refScroll.scrollTop / (pageSize * rowHeight)) + 1 || 1
currentPageReal = currentPageReal > maxPage ? maxPage : currentPageReal
if (currentPageReal !== currentPage) {
this.updateTable()
shouldUpdate = false
}
debug &&
console.log('shouldUpdate:currentPageReal', {
currentPageReal,
currentPage,
shouldUpdate,
});
}
debug &&
console.log('shouldUpdate:currentPageReal', {
currentPageReal,
currentPage,
shouldUpdate,
})
}
if (shouldUpdate) {
const {
refPageBoundaryBefore,
refPageBoundaryAfter,
} = this.ioTargetState;
if (shouldUpdate) {
const { refPageBoundaryBefore, refPageBoundaryAfter } = this.ioTargetState
switch (direction) {
case 'up':
if (
this.state.hasCacheAfter &&
currentPage < maxPage - 2 && // Bug fix: 如果是最后三页向后点击切换,需要刷新视图,否则页码表记停留在前一页
refPageBoundaryBefore &&
refPageBoundaryBefore.intersectionRatio > 0
)
shouldUpdate = false;
break;
switch (direction) {
case 'up':
if (
this.state.hasCacheAfter &&
currentPage < maxPage - 2 && // Bug fix: 如果是最后三页向后点击切换,需要刷新视图,否则页码表记停留在前一页
refPageBoundaryBefore &&
refPageBoundaryBefore.intersectionRatio > 0
)
shouldUpdate = false
break
case 'down':
if (
this.state.currentPage === currentPage &&
this.state.hasCacheAfter && // Bug fix: 可能存在3页数据已经加载到了, 但之前没有刷新的情况,所以需要刷新,判断特征是之前的数据小于3页
refPageBoundaryAfter &&
refPageBoundaryAfter.intersectionRatio > 0
)
shouldUpdate = false;
}
case 'down':
if (
this.state.currentPage === currentPage &&
this.state.hasCacheAfter && // Bug fix: 可能存在3页数据已经加载到了, 但之前没有刷新的情况,所以需要刷新,判断特征是之前的数据小于3页
refPageBoundaryAfter &&
refPageBoundaryAfter.intersectionRatio > 0
)
shouldUpdate = false
}
debug &&
console.log('shouldUpdate:verboseBoundary', {
shouldUpdate,
direction,
dataSource,
Before:
refPageBoundaryBefore && refPageBoundaryBefore.intersectionRatio,
After: refPageBoundaryAfter && refPageBoundaryAfter.intersectionRatio,
});
}
debug &&
console.log('shouldUpdate:verboseBoundary', {
shouldUpdate,
direction,
dataSource,
Before: refPageBoundaryBefore && refPageBoundaryBefore.intersectionRatio,
After: refPageBoundaryAfter && refPageBoundaryAfter.intersectionRatio,
})
}
if (shouldUpdate) {
shouldUpdate = [1, maxPage, maxPage - 1, maxPage - 2].includes(
currentPage,
)
? dataSource.length > 0
: [
// 如果已经加载3页数据,需要更新视图,否则不在 fullLoading 状态,即使数据不满3页也需要更新视图
...(this.fullLoading ? [] : [0, pageSize, pageSize * 2]),
pageSize * 3,
].includes(dataSource.length);
if (shouldUpdate) {
shouldUpdate = [1, maxPage, maxPage - 1, maxPage - 2].includes(currentPage)
? dataSource.length > 0
: [
// 如果已经加载3页数据,需要更新视图,否则不在 fullLoading 状态,即使数据不满3页也需要更新视图
...(this.fullLoading ? [] : [0, pageSize, pageSize * 2]),
pageSize * 3,
].includes(dataSource.length)
debug &&
console.log('shouldUpdate:3Page', {
currentPage,
dataSource,
shouldUpdate,
state: this.state,
nextState,
});
}
debug &&
console.log('shouldUpdate:3Page', {
currentPage,
dataSource,
shouldUpdate,
state: this.state,
nextState,
})
}
return shouldUpdate;
}
componentDidUpdate(preProps, preState) {
const {
hasCache,
hasCacheBefore,
currentPage,
dataSource,
maxPage,
} = this.state;
const { pageSize, debug } = this.props;
return shouldUpdate
}
componentDidUpdate(preProps, preState) {
const { hasCache, hasCacheBefore, currentPage, dataSource, maxPage } = this.state
const { pageSize, debug } = this.props
if (!this.isInitial) {
let before, after;
if (!this.isInitial) {
let before, after
if (hasCache && hasCacheBefore) {
if (currentPage === 1 || currentPage === maxPage - 1) {
before = 0;
after = pageSize - 1;
} else if (currentPage === maxPage) {
before = 0;
after = dataSource.length - 1;
} else {
before = pageSize;
after = pageSize * 2 - 1;
}
if (hasCache && hasCacheBefore) {
if (currentPage === 1 || currentPage === maxPage - 1) {
before = 0
after = pageSize - 1
} else if (currentPage === maxPage) {
before = 0
after = dataSource.length - 1
} else {
before = pageSize
after = pageSize * 2 - 1
}
if (this.refPageBoundaryBefore !== this.refTable.children[before]) {
this.refPageBoundaryBefore &&
this.io.unobserve(this.refPageBoundaryBefore);
this.refPageBoundaryAfter &&
this.io.unobserve(this.refPageBoundaryAfter);
if (this.refPageBoundaryBefore !== this.refTable.children[before]) {
this.refPageBoundaryBefore && this.io.unobserve(this.refPageBoundaryBefore)
this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter)
this.refPageBoundaryBefore = this.refTable.children[before];
this.refPageBoundaryAfter = this.refTable.children[after];
this.refPageBoundaryBefore = this.refTable.children[before]
this.refPageBoundaryAfter = this.refTable.children[after]
this.refPageBoundaryAfter &&
this.io.observe(this.refPageBoundaryAfter);
this.refPageBoundaryBefore &&
this.io.observe(this.refPageBoundaryBefore);
this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter)
this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore)
debug &&
this.refPageBoundaryBefore &&
console.log(
'componentDidUpdate',
this.refPageBoundaryBefore.innerText,
);
debug &&
this.refPageBoundaryAfter &&
console.log(
'componentDidUpdate',
this.refPageBoundaryAfter.innerText,
);
debug &&
this.refPageBoundaryBefore &&
console.log('componentDidUpdate', this.refPageBoundaryBefore.innerText)
debug &&
this.refPageBoundaryAfter &&
console.log('componentDidUpdate', this.refPageBoundaryAfter.innerText)
this.isPageBoundary = true;
}
}
const emptyPlaceholder = this.refRoot.querySelector(
'.ant-table-placeholder',
);
emptyPlaceholder && (emptyPlaceholder.style.display = 'none');
}
}
componentWillUnmount() {
this.props.onScroll &&
this.refScroll.removeEventListener('scroll', this.props.onScroll);
this.io.disconnect();
}
isInitial = true; // 初始状态,未渲染任何数据
isReady = false; // 已渲染首屏数据,可交互的状态
isPageBoundary = false; // 当前页,上下边界更新
isPaginationClick = false;
refUpperPlaceholder = null;
refUnderPlaceholder = null;
refLoadingPlaceholder = null;
refScroll = null;
refTable = null;
refFooter = null;
refPageBoundaryBefore = null; // 当前页的第一条DOM数据
refPageBoundaryAfter = null; // 当前页的最后一条DOM数据
ioTargetState = {
refUnderPlaceholder: null,
refUpperPlaceholder: null,
refTable: null,
refPageBoundaryBefore: null,
refPageBoundaryAfter: null,
};
createLoadingPlaceholder() {
const refLoadingPlaceholder = document.createElement('div');
refLoadingPlaceholder.setAttribute('id', 'refLoadingPlaceholder');
const clientRect = this.refScroll.getBoundingClientRect();
refLoadingPlaceholder.setAttribute(
'style',
`position:fixed; width:${clientRect.width}px; height:${
clientRect.height
}px`,
);
this.isPageBoundary = true
}
}
const emptyPlaceholder = this.refRoot.querySelector('.ant-table-placeholder')
emptyPlaceholder && (emptyPlaceholder.style.display = 'none')
}
}
componentWillUnmount() {
this.props.onScroll && this.refScroll.removeEventListener('scroll', this.props.onScroll)
this.io.disconnect()
}
isInitial = true // 初始状态,未渲染任何数据
isReady = false // 已渲染首屏数据,可交互的状态
isPageBoundary = false // 当前页,上下边界更新
isPaginationClick = false
refUpperPlaceholder = null
refUnderPlaceholder = null
refLoadingPlaceholder = null
refScroll = null
refTable = null
refFooter = null
refPageBoundaryBefore = null // 当前页的第一条DOM数据
refPageBoundaryAfter = null // 当前页的最后一条DOM数据
ioTargetState = {
refUnderPlaceholder: null,
refUpperPlaceholder: null,
refTable: null,
refPageBoundaryBefore: null,
refPageBoundaryAfter: null,
}
createLoadingPlaceholder() {
const refLoadingPlaceholder = document.createElement('div')
refLoadingPlaceholder.setAttribute('id', 'refLoadingPlaceholder')
const clientRect = this.refScroll.getBoundingClientRect()
refLoadingPlaceholder.setAttribute(
'style',
`position:fixed; width:${clientRect.width}px; height:${clientRect.height}px`,
)
this.refScroll.insertBefore(
refLoadingPlaceholder,
this.refScroll.firstChild,
);
this.refLoadingPlaceholder = refLoadingPlaceholder;
}
this.refScroll.insertBefore(refLoadingPlaceholder, this.refScroll.firstChild)
this.refLoadingPlaceholder = refLoadingPlaceholder
}
// 创建底部填充块
createUnderPlaceholder() {
const refUnderPlaceholder = document.createElement('div');
refUnderPlaceholder.setAttribute('id', 'refUnderPlaceholder');
this.refScroll.appendChild(refUnderPlaceholder);
this.refUnderPlaceholder = refUnderPlaceholder;
}
// 创建顶部填充块
createUpperPlaceholder() {
const refUpperPlaceholder = document.createElement('div');
refUpperPlaceholder.setAttribute('id', 'refUpperPlaceholder');
this.refScroll.insertBefore(refUpperPlaceholder, this.refScroll.firstChild);
this.refUpperPlaceholder = refUpperPlaceholder;
}
// 创建底部填充块
createUnderPlaceholder() {
const refUnderPlaceholder = document.createElement('div')
refUnderPlaceholder.setAttribute('id', 'refUnderPlaceholder')
this.refScroll.appendChild(refUnderPlaceholder)
this.refUnderPlaceholder = refUnderPlaceholder
}
// 创建顶部填充块
createUpperPlaceholder() {
const refUpperPlaceholder = document.createElement('div')
refUpperPlaceholder.setAttribute('id', 'refUpperPlaceholder')
this.refScroll.insertBefore(refUpperPlaceholder, this.refScroll.firstChild)
this.refUpperPlaceholder = refUpperPlaceholder
}
scrollToPage = (...args) => {
const { pageSize } = this.props;
const { rowHeight } = this.state;
const [page] = args;
this.refScroll.scrollTop = (page - 1) * pageSize * rowHeight + 1; // Bug fix: + 1个像素,点击页码向后翻页时存在少一个像素就变成上一页的bug
this.isPaginationClick = true;
this.props.pagination &&
this.props.pagination.onChange &&
this.props.pagination.onChange(...args);
};
updateTable = () => {
const { clientHeight: tableHeight } = this.refTable;
const { scrollTop } = this.refScroll;
let { rowHeight, maxPage } = this.state;
const { pageSize, total, debug } = this.props;
scrollToPage = (...args) => {
const { pageSize } = this.props
const { rowHeight } = this.state
const [page] = args
this.refScroll.scrollTop = (page - 1) * pageSize * rowHeight + 1 // Bug fix: + 1个像素,点击页码向后翻页时存在少一个像素就变成上一页的bug
this.isPaginationClick = true
this.props.pagination && this.props.pagination.onChange && this.props.pagination.onChange(...args)
}
updateTable = () => {
const { clientHeight: tableHeight } = this.refTable
const { scrollTop } = this.refScroll
let { rowHeight, maxPage } = this.state
const { pageSize, total, debug } = this.props
if (this.isInitial) {
// 还在初始状态
maxPage = Math.ceil(total / pageSize);
const {
dataSource: { length },
} = this.state;
rowHeight = tableHeight / length;
if (rowHeight) {
// 当行高出现,表示初次呈现数据数时
this.isInitial = false;
this.initialReslove();
}
}
let currentPage = Math.floor(scrollTop / (pageSize * rowHeight)) + 1 || 1;
currentPage = currentPage > maxPage ? maxPage : currentPage;
if (this.isInitial) {
// 还在初始状态
maxPage = Math.ceil(total / pageSize)
const {
dataSource: { length },
} = this.state
rowHeight = tableHeight / length
if (rowHeight) {
// 当行高出现,表示初次呈现数据数时
this.isInitial = false
this.initialReslove()
}
}
let currentPage = Math.floor(scrollTop / (pageSize * rowHeight)) + 1 || 1
currentPage = currentPage > maxPage ? maxPage : currentPage
debug &&
console.log('updateTable', {
currentPage,
});
this.setState(
{
direction:
this.refScroll.scrollTop - this.state.scrollTop < 0 ? 'up' : 'down',
scrollTop: this.refScroll.scrollTop,
maxPage,
currentPage,
rowHeight,
},
// () => console.log('computeState done', this.state),
);
};
toggleObserver(condition = true) {
if (condition) {
this.io.observe(this.refUpperPlaceholder);
this.io.observe(this.refUnderPlaceholder);
this.io.observe(this.refTable);
this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore);
this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter);
} else {
this.io.unobserve(this.refUpperPlaceholder);
this.io.unobserve(this.refUnderPlaceholder);
this.io.unobserve(this.refTable);
this.refPageBoundaryBefore &&
this.io.unobserve(this.refPageBoundaryBefore);
this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter);
}
}
render() {
const {
pageSize,
loadingIndicator,
loading,
total,
columns,
debug,
forwardedRef,
pagination,
...rest
} = this.props;
debug &&
console.log('updateTable', {
currentPage,
})
this.setState(
{
direction: this.refScroll.scrollTop - this.state.scrollTop < 0 ? 'up' : 'down',
scrollTop: this.refScroll.scrollTop,
maxPage,
currentPage,
rowHeight,
},
// () => console.log('computeState done', this.state),
)
}
toggleObserver(condition = true) {
if (condition) {
this.io.observe(this.refUpperPlaceholder)
this.io.observe(this.refUnderPlaceholder)
this.io.observe(this.refTable)
this.refPageBoundaryBefore && this.io.observe(this.refPageBoundaryBefore)
this.refPageBoundaryAfter && this.io.observe(this.refPageBoundaryAfter)
} else {
this.io.unobserve(this.refUpperPlaceholder)
this.io.unobserve(this.refUnderPlaceholder)
this.io.unobserve(this.refTable)
this.refPageBoundaryBefore && this.io.unobserve(this.refPageBoundaryBefore)
this.refPageBoundaryAfter && this.io.unobserve(this.refPageBoundaryAfter)
}
}
render() {
const {
pageSize,
loadingIndicator,
loading,
total,
columns,
debug,
forwardedRef,
pagination,
...rest
} = this.props
const {
dataSource,
upperHeight,
underHeight,
cacheData,
currentPage,
} = this.state;
const { dataSource, upperHeight, underHeight, cacheData, currentPage } = this.state
this.fullLoading = !cacheData[currentPage];
const { fullLoading } = this;
debug && console.log('%c Rendering', 'color:#f00;font-weight:bold');
this.fullLoading = !cacheData[currentPage]
const { fullLoading } = this
debug && console.log('%c Rendering', 'color:#f00;font-weight:bold')
return (
<Fragment>
<InfinityTable.LoadingPlaceHolder
domNode={this.refLoadingPlaceholder}
loading={fullLoading}
loadingIndicator={<Spin tip="Loading..." />}
/>
<InfinityTable.PlaceHolder
height={upperHeight}
domNode={this.refUpperPlaceholder}
loading={loading && !fullLoading}
loadingIndicator={loadingIndicator}
/>
<InfinityTable.PlaceHolder
height={underHeight}
domNode={this.refUnderPlaceholder}
loading={loading && !fullLoading}
loadingIndicator={loadingIndicator}
/>
{!this.isInitial &&
pagination &&
['top', 'both'].includes(pagination.position) && (
<Pagination
showQuickJumper
{...pagination}
onChange={this.scrollToPage}
current={currentPage}
pageSize={pageSize}
showSizeChanger={false}
total={total}
className={`infinity-page-table-pagination ${
pagination && pagination.className ? pagination.className : ''
}`}
/>
)}
<Table
rowKey={record => record.key}
{...rest}
ref={forwardedRef}
columns={columns}
dataSource={dataSource}
pagination={false}
className={`infinity-page-table ${
rest.className ? rest.className : ''
}`}
/>
{!this.isInitial &&
pagination &&
[undefined, 'bottom', 'both'].includes(pagination.position) && (
<Pagination
showQuickJumper
{...pagination}
onChange={this.scrollToPage}
current={currentPage}
pageSize={pageSize}
showSizeChanger={false}
total={total}
className={`infinity-page-table-pagination ${
pagination && pagination.className ? pagination.className : ''
}`}
/>
)}
</Fragment>
);
}
return (
<Fragment>
<InfinityTable.LoadingPlaceHolder
domNode={this.refLoadingPlaceholder}
loading={fullLoading}
loadingIndicator={<Spin tip="Loading..." />}
/>
<InfinityTable.PlaceHolder
height={upperHeight}
domNode={this.refUpperPlaceholder}
loading={loading && !fullLoading}
loadingIndicator={loadingIndicator}
/>
<InfinityTable.PlaceHolder
height={underHeight}
domNode={this.refUnderPlaceholder}
loading={loading && !fullLoading}
loadingIndicator={loadingIndicator}
/>
{total && pagination && ['top', 'both'].includes(pagination.position) && (
<Pagination
showQuickJumper
{...pagination}
onChange={this.scrollToPage}
current={currentPage}
pageSize={pageSize}
showSizeChanger={false}
total={total}
className={`infinity-page-table-pagination ${
pagination && pagination.className ? pagination.className : ''
}`}
/>
)}
<Table
rowKey={record => record.key}
{...rest}
ref={forwardedRef}
columns={columns}
dataSource={dataSource}
pagination={false}
className={`infinity-page-table ${rest.className ? rest.className : ''}`}
/>
{total && pagination && [undefined, 'bottom', 'both'].includes(pagination.position) && (
<Pagination
showQuickJumper
{...pagination}
onChange={this.scrollToPage}
current={currentPage}
pageSize={pageSize}
showSizeChanger={false}
total={total}
className={`infinity-page-table-pagination ${
pagination && pagination.className ? pagination.className : ''
}`}
/>
)}
</Fragment>
)
}
}
InfinityTable.defaultProps = {
// loading 效果, A visual react component for Loading status
loadingIndicator: (
<div
style={{
textAlign: 'center',
paddingTop: 20,
paddingBottom: 20,
border: '1px solid #e8e8e8',
}}
>
<Spin tip="Loading..." />
</div>
),
pagination: { defaultCurrent: 1 }, // 分页器
onScroll: null, // 滚动事件
onFetch: noop, // 滚动到低部触发Fetch方法
bidirectionalCachePages: Infinity, // 当前页前后的缓存页码数量,默认为无限
total: 0, // 总共数据条数
debug: false, // display console log for debug
loading: false, // 是否loading状态
pageSize: 30, // 每次Loading数据量,pageSize * 3 = 最大真实DOM大小,Reality DOM row count
};
// loading 效果, A visual react component for Loading status
loadingIndicator: (
<div
style={{
textAlign: 'center',
paddingTop: 20,
paddingBottom: 20,
border: '1px solid #e8e8e8',
}}
>
<Spin tip="Loading..." />
</div>
),
pagination: { defaultCurrent: 1 }, // 分页器
onScroll: null, // 滚动事件
onFetch: noop, // 滚动到低部触发Fetch方法
bidirectionalCachePages: Infinity, // 当前页前后的缓存页码数量,默认为无限
total: 0, // 总共数据条数
debug: false, // display console log for debug
loading: false, // 是否loading状态
pageSize: 30, // 每次Loading数据量,pageSize * 3 = 最大真实DOM大小,Reality DOM row count
}
InfinityTable.propTypes = {
// loading 效果
className: string,
loadingIndicator: element,
onScroll: func, // 滚动事件
pagination: oneOfType([
bool,
shape({
className: string,
position: oneOf(['both', 'top', 'bottom']),
className: string,
defaultCurrent: number,
hideOnSinglePage: bool,
itemRender: func,
showQuickJumper: bool,
showTotal: func,
simple: bool,
size: string,
onChange: func,
}),
]),
onFetch: func.isRequired, // 滚动触发Fetch方法
pageSize: number.isRequired,
bidirectionalCachePages: number.isRequired,
total: number.isRequired,
dataSource: array.isRequired,
columns: array.isRequired,
forwardedRef: object,
debug: bool,
loading: bool.isRequired,
};
// loading 效果
className: string,
loadingIndicator: element,
onScroll: func, // 滚动事件
pagination: oneOfType([
bool,
shape({
className: string,
position: oneOf(['both', 'top', 'bottom']),
className: string,
defaultCurrent: number,
hideOnSinglePage: bool,
itemRender: func,
showQuickJumper: bool,
showTotal: func,
simple: bool,
size: string,
onChange: func,
}),
]),
onFetch: func.isRequired, // 滚动触发Fetch方法
pageSize: number.isRequired,
bidirectionalCachePages: number.isRequired,
total: number.isRequired,
dataSource: array.isRequired,
columns: array.isRequired,
forwardedRef: object,
debug: bool,
loading: bool.isRequired,
}
export default React.forwardRef((props, ref) => (
<InfinityTable {...props} forwardedRef={ref} />
));
export default React.forwardRef((props, ref) => <InfinityTable {...props} forwardedRef={ref} />)
export { InfinityTable }

@@ -84,2 +84,2 @@ import { bool, number, array, object, func } from 'prop-types';

export default SumTable;
export default SumTable;

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc