Browse Source

Add react-lazy-load for Transfer perfermance, close #2860

pull/3715/head
afc163 8 years ago
parent
commit
7373ce0758
  1. 64
      components/transfer/demo/large-data.md
  2. 5
      components/transfer/index.en-US.md
  3. 15
      components/transfer/index.tsx
  4. 3
      components/transfer/index.zh-CN.md
  5. 28
      components/transfer/list.tsx
  6. 1
      components/transfer/style/index.less
  7. 1
      package.json
  8. 2
      typings/custom-typings.d.ts

64
components/transfer/demo/large-data.md

@ -0,0 +1,64 @@
---
order: 4
debug: true
title:
zh-CN: 大数据性能测试
en-US: Performance Test
---
## zh-CN
2000 条数据。
## en-US
2000 items.
````jsx
import { Transfer } from 'antd';
const App = React.createClass({
getInitialState() {
return {
mockData: [],
targetKeys: [],
};
},
componentDidMount() {
this.getMock();
},
getMock() {
const targetKeys = [];
const mockData = [];
for (let i = 0; i < 2000; i++) {
const data = {
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`,
chosen: Math.random() * 2 > 1,
};
if (data.chosen) {
targetKeys.push(data.key);
}
mockData.push(data);
}
this.setState({ mockData, targetKeys });
},
handleChange(targetKeys, direction, moveKeys) {
console.log(targetKeys, direction, moveKeys);
this.setState({ targetKeys });
},
render() {
return (
<Transfer
dataSource={this.state.mockData}
targetKeys={this.state.targetKeys}
onChange={this.handleChange}
render={item => item.title}
/>
);
},
});
ReactDOM.render(<App />, mountNode);
````

5
components/transfer/index.en-US.md

@ -15,7 +15,6 @@ To transfer the elements between two columns in an intuitive and efficient way.
## API
| Property | Description | Type | Default |
|-----------|------------------------------------------|------------|--------|
| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column. Except the elements whose keys are included in `targetKeys` prop. | Array | [] |
@ -31,11 +30,11 @@ To transfer the elements between two columns in an intuitive and efficient way.
| searchPlaceholder | The hint text of the search box. | String | 'Search here' |
| notFoundContent | Text to display when a column is empty. | React.node | 'The list is empty' |
| footer | A function used for rendering the footer. | Function(props) | |
| lazy | property of [react-lazy-load](https://github.com/loktar00/react-lazy-load) for lazy rendering items | Object | `{ height: 32, offset: 32 }` |
## Warning
According the [standard](http://facebook.github.io/react/docs/multiple-components.html#dynamic-children) of React, the key should always be supplied directly to the elements in the array. In Transfer, the keys should be set on the elements included in `dataSource` array. By default, `key` property is used as an unique identifier.
According the [standard](http://facebook.github.io/react/docs/multiple-components.html#dynamic-children) of React, the key should always be supplied directly to the elements in the array. In Transfer, the keys should be set on the elements included in `dataSource` array. By default, `key` property is used as an unique identifier.
If there's no `key` in your data, you should use `rowKey` to specify the key that will be used for uniquely identify each element.
```jsx

15
components/transfer/index.tsx

@ -35,6 +35,7 @@ export interface TransferProps {
filterOption: (inputValue: any, item: any) => boolean;
body?: (props: any) => any;
rowKey?: (record: any) => string;
lazy?: {};
}
export interface TransferContext {
@ -73,6 +74,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
body: PropTypes.func,
footer: PropTypes.func,
rowKey: PropTypes.func,
lazy: PropTypes.object,
};
static contextTypes = {
@ -255,7 +257,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
const {
prefixCls = 'ant-transfer', operations = [], showSearch, notFoundContent,
searchPlaceholder, body, footer, listStyle, className = '',
filterOption, render,
filterOption, render, lazy,
} = this.props;
const { leftFilter, rightFilter, leftCheckedKeys, rightCheckedKeys } = this.state;
@ -271,7 +273,8 @@ export default class Transfer extends React.Component<TransferProps, any> {
const titles = this.getTitles();
return (
<div className={cls}>
<List titleText={titles[0]}
<List
titleText={titles[0]}
dataSource={leftDataSource}
filter={leftFilter}
filterOption={filterOption}
@ -288,8 +291,10 @@ export default class Transfer extends React.Component<TransferProps, any> {
body={body}
footer={footer}
prefixCls={`${prefixCls}-list`}
lazy={lazy}
/>
<Operation rightActive={rightActive}
<Operation
rightActive={rightActive}
rightArrowText={operations[0]}
moveToRight={this.moveToRight}
leftActive={leftActive}
@ -297,7 +302,8 @@ export default class Transfer extends React.Component<TransferProps, any> {
moveToLeft={this.moveToLeft}
className={`${prefixCls}-operation`}
/>
<List titleText={titles[1]}
<List
titleText={titles[1]}
dataSource={rightDataSource}
filter={rightFilter}
filterOption={filterOption}
@ -314,6 +320,7 @@ export default class Transfer extends React.Component<TransferProps, any> {
body={body}
footer={footer}
prefixCls={`${prefixCls}-list`}
lazy={lazy}
/>
</div>
);

3
components/transfer/index.zh-CN.md

@ -16,7 +16,6 @@ title: Transfer
## API
| 参数 | 说明 | 类型 | 默认值 |
|-----------|------------------------------------------|------------|--------|
| dataSource | 数据源,其中的数据将会被渲染到左边一栏中,`targetKeys` 中指定的除外。 | Array | [] |
@ -33,7 +32,7 @@ title: Transfer
| searchPlaceholder | 搜索框的默认值 | String | '请输入搜索内容' |
| notFoundContent | 当列表为空时显示的内容 | React.node | '列表为空' |
| footer | 底部渲染函数 | Function(props) | |
| lazy | Transfer 使用了 [react-lazy-load](https://github.com/loktar00/react-lazy-load) 优化性能,这里可以设置相关参数 | Object | `{ height: 32, offset: 32 }` |
## 注意

28
components/transfer/list.tsx

@ -5,6 +5,7 @@ import classNames from 'classnames';
import Animate from 'rc-animate';
import PureRenderMixin from 'rc-util/lib/PureRenderMixin';
import assign from 'object-assign';
import Lazyload from 'react-lazy-load';
import { TransferItem } from './index';
function noop() {
@ -35,6 +36,7 @@ export interface TransferListProps {
position?: string;
notFoundContent?: React.ReactNode | string;
filterOption: (filterText: any, item: any) => boolean;
lazy?: {};
}
export interface TransferListContext {
@ -135,7 +137,7 @@ export default class TransferList extends React.Component<TransferListProps, any
}
render() {
const { prefixCls, dataSource, titleText, filter, checkedKeys,
const { prefixCls, dataSource, titleText, filter, checkedKeys, lazy,
body = noop, footer = noop, showSearch, render = noop, style } = this.props;
let { searchPlaceholder, notFoundContent } = this.props;
@ -177,16 +179,22 @@ export default class TransferList extends React.Component<TransferListProps, any
[`${prefixCls}-content-item`]: true,
[`${prefixCls}-content-item-disabled`]: item.disabled,
});
const lazyProps = assign({
height: 32,
offset: 320,
}, lazy);
return (
<li
key={item.key}
className={className}
title={renderedText}
onClick={item.disabled ? undefined : () => this.handleSelect(item)}
>
<Checkbox checked={checkedKeys.some(key => key === item.key)} disabled={item.disabled} />
<span>{renderedEl}</span>
</li>
<Lazyload key={item.key} {...lazyProps}>
<li
key={item.key}
className={className}
title={renderedText}
onClick={item.disabled ? undefined : () => this.handleSelect(item)}
>
<Checkbox checked={checkedKeys.some(key => key === item.key)} disabled={item.disabled} />
<span>{renderedEl}</span>
</li>
</Lazyload>
);
});

1
components/transfer/style/index.less

@ -98,6 +98,7 @@
white-space: nowrap;
text-overflow: ellipsis;
padding: 7px 15px;
min-height: 32px;
transition: all 0.3s ease;
}

1
package.json

@ -71,6 +71,7 @@
"rc-tree-select": "~1.8.0",
"rc-upload": "~2.2.0",
"rc-util": "^4.0.1",
"react-lazy-load": "^3.0.10",
"react-slick": "~0.14.2",
"shallowequal": "^0.2.2",
"warning": "~3.0.0"

2
typings/custom-typings.d.ts

@ -76,6 +76,8 @@ declare module 'rc-collapse';
declare module 'rc-form*';
declare module 'react-lazy-load';
declare var process: {
env: {
NODE_ENV: string

Loading…
Cancel
Save