diff --git a/README.md b/README.md index c1f978513..c76ea097a 100644 --- a/README.md +++ b/README.md @@ -109,11 +109,11 @@ React.render(, mountNode); - + diff --git a/package.json b/package.json index 0e7789cb5..84d436cab 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "dependencies": { "object-path": "^0.11.1", "rc-util": "3.x", - "shallowequal": "^0.2.2" + "shallowequal": "^0.2.2", + "warning": "^3.0.0" }, "devDependencies": { "expect.js": "~0.3.1", diff --git a/src/Table.jsx b/src/Table.jsx index 04b52ceb8..420de16f0 100644 --- a/src/Table.jsx +++ b/src/Table.jsx @@ -1,7 +1,7 @@ import React, { PropTypes } from 'react'; import TableRow from './TableRow'; import TableHeader from './TableHeader'; -import { measureScrollbar, debounce } from './utils'; +import { measureScrollbar, debounce, warningOnce } from './utils'; import shallowequal from 'shallowequal'; import addEventListener from 'rc-util/lib/Dom/addEventListener'; import ColumnManager from './ColumnManager'; @@ -77,7 +77,7 @@ const Table = React.createClass({ if (props.defaultExpandAllRows) { for (let i = 0; i < rows.length; i++) { const row = rows[i]; - expandedRowKeys.push(this.getRowKey(row)); + expandedRowKeys.push(this.getRowKey(row, i)); rows = rows.concat(row[props.childrenColumnName] || []); } } else { @@ -141,25 +141,25 @@ const Table = React.createClass({ this.props.onExpandedRowsChange(expandedRowKeys); }, - onExpanded(expanded, record, e) { + onExpanded(expanded, record, e, index) { if (e) { e.preventDefault(); e.stopPropagation(); } const info = this.findExpandedRow(record); if (typeof info !== 'undefined' && !expanded) { - this.onRowDestroy(record); + this.onRowDestroy(record, index); } else if (!info && expanded) { const expandedRows = this.getExpandedRows().concat(); - expandedRows.push(this.getRowKey(record)); + expandedRows.push(this.getRowKey(record, index)); this.onExpandedRowsChange(expandedRows); } this.props.onExpand(expanded, record); }, - onRowDestroy(record) { + onRowDestroy(record, rowIndex) { const expandedRows = this.getExpandedRows().concat(); - const rowKey = this.getRowKey(record); + const rowKey = this.getRowKey(record, rowIndex); let index = -1; expandedRows.forEach((r, i) => { if (r === rowKey) { @@ -174,10 +174,14 @@ const Table = React.createClass({ getRowKey(record, index) { const rowKey = this.props.rowKey; - if (typeof rowKey === 'function') { - return rowKey(record, index); - } - return typeof record[rowKey] !== 'undefined' ? record[rowKey] : index; + const key = (typeof rowKey === 'function') ? + rowKey(record, index) : record[rowKey]; + warningOnce( + key !== undefined, + 'Each record in table should have a unique `key` prop,' + + 'or set `rowKey` to an unique primary key.' + ); + return key; }, getExpandedRows() { @@ -299,7 +303,7 @@ const Table = React.createClass({ const record = data[i]; const key = this.getRowKey(record, i); const childrenColumn = record[childrenColumnName]; - const isRowExpanded = this.isRowExpanded(record); + const isRowExpanded = this.isRowExpanded(record, i); let expandedRowContent; if (expandedRowRender && isRowExpanded) { expandedRowContent = expandedRowRender(record, i, indent); @@ -598,13 +602,13 @@ const Table = React.createClass({ } }, - findExpandedRow(record) { - const rows = this.getExpandedRows().filter(i => i === this.getRowKey(record)); + findExpandedRow(record, index) { + const rows = this.getExpandedRows().filter(i => i === this.getRowKey(record, index)); return rows[0]; }, - isRowExpanded(record) { - return typeof this.findExpandedRow(record) !== 'undefined'; + isRowExpanded(record, index) { + return typeof this.findExpandedRow(record, index) !== 'undefined'; }, detectScrollTarget(e) { diff --git a/src/TableRow.jsx b/src/TableRow.jsx index 6c3898b02..781d08b49 100644 --- a/src/TableRow.jsx +++ b/src/TableRow.jsx @@ -60,7 +60,8 @@ const TableRow = React.createClass({ }, componentWillUnmount() { - this.props.onDestroy(this.props.record); + const { record, onDestroy, index } = this.props; + onDestroy(record, index); if (this.unsubscribe) { this.unsubscribe(); } @@ -77,7 +78,7 @@ const TableRow = React.createClass({ onExpand, } = this.props; if (expandable && expandRowByClick) { - onExpand(!expanded, record); + onExpand(!expanded, record, index); } onRowClick(record, index, event); }, diff --git a/src/utils.js b/src/utils.js index f8c44ba3e..f76b1d9de 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,3 +1,5 @@ +import warning from 'warning'; + let scrollbarWidth; // Measure scrollbar width for padding body during modal show/hide @@ -52,3 +54,11 @@ export function debounce(func, wait, immediate) { } }; } + +const warned = {}; +export function warningOnce(condition, format, args) { + if (!warned[format]) { + warning(condition, format, args); + warned[format] = true; + } +}
rowKeystring or Function(record, index):stringstring or Function(record):string 'key' If rowKey is string, `record[rowKey]` will be used as key. - If rowKey is function, the return value of `rowKey(record, index)` will be use as key. + If rowKey is function, the return value of `rowKey(record)` will be use as key.