我目前的实施:
export const SORT_ORDER = {
ASC: "ascending",
DESC: "descending",
OTHER: "other"
};
export default class Table extends React.Component {
constructor(props) {
super(props);
this.sortIcon = new Map();
this.sortIcon.set(SORT_ORDER.ASC, sortAsc);
this.sortIcon.set(SORT_ORDER.DESC, sortDesc);
this.sortIcon.set(SORT_ORDER.OTHER, sortOther);
this.state = {
sortField: this.props.defaultSortColumn,
sortOrder: this.props.defaultSortOrder
};
}
componentDidMount() {
this.sort(this.props.defaultSortColumn, this.props.defaultSortOrder)();
}
retrieveOrder = (columnId) => {
return columnId === this.state.sortField ? this.state.sortOrder : SORT_ORDER.OTHER;
};
nextOrder = (current) => {
if (current === SORT_ORDER.DESC) {
return SORT_ORDER.ASC;
} else if (current === SORT_ORDER.ASC) {
return SORT_ORDER.DESC;
} else {
return this.props.defaultSortOrder;
}
};
sort = (columnId, order) => () => {
let descriptor = this.props.structure[columnId];
let values = this.props.value.slice();
let orderFactor = order === SORT_ORDER.ASC ? 1 : -1;
values.sort((a, b) => {
let first = descriptor.render(a);
let second = descriptor.render(b);
return first > second ? orderFactor : first < second ? -orderFactor : 0;
});
this.setState({
sortField: columnId,
sortOrder: order
});
this.props.onSort(values);
};
renderHeader = (id, descriptor) => {
let order = this.retrieveOrder(id);
let iconSrc = this.sortIcon.get(order);
let nextOrder = this.nextOrder(this.retrieveOrder(id));
return (
<th key={id} className={descriptor.headStyle}>
<a href="#" aria-sort={order} onClick={this.sort(id, nextOrder)}>
<img src={iconSrc}/>
{descriptor.label}
</a>
</th>
);
};
render() {
return (
<table>
Table structure
</table>
);
}
}
父组件以下一种方式声明它:
<Table structure={this.tableHeader} value={this.state.tableValue} onSort={this.handleChange('tableValue')}
defaultSortColumn="created" defaultSortOrder={SORT_ORDER.DESC} />
表值在props中定义为value
。 onSort
是一个更改父组件状态的函数=&gt;它会更改表值。此外,我还需要defaultSortColumn
和defaultSortOrder
对表格进行排序后对其进行排序。
问题是我的表可以在页面上多次声明。
所以,
1)我无法将表值存储在其状态中。我应该吗?
2)如何在不使用componentDidMount
的情况下实现默认排序?使用当前实现时,默认排序仅在调用componentDidMount
时发生一次,但我在页面上有超过1个<Table/>
组件。
我尝试使用componentWillReceiveProps
函数,但在<Table/>
函数中更改sort
状态时也会调用它。所以我不能用它。
答案 0 :(得分:0)
我的最终解决方案是:
root@beaglebone:/opt/scripts/boot# ifconfig
eth0 Link encap:Ethernet HWaddr 04:a3:16:e1:5d:39
UP BROADCAST MULTICAST DYNAMIC MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Interrupt:173
eth1 Link encap:Ethernet HWaddr 20:c9:d0:29:e0:88
inet addr:169.254.84.230 Bcast:169.254.255.255 Mask:255.255.0.0
inet6 addr: fe80::22c9:d0ff:fe29:e088/64 Scope:Link
UP BROADCAST RUNNING MULTICAST DYNAMIC MTU:1500 Metric:1
RX packets:56 errors:0 dropped:0 overruns:0 frame:0
TX packets:136 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:6708 (6.5 KiB) TX bytes:36844 (35.9 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:236 errors:0 dropped:0 overruns:0 frame:0
TX packets:236 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:18852 (18.4 KiB) TX bytes:18852 (18.4 KiB)
usb0 Link encap:Ethernet HWaddr 04:a3:16:e1:5d:3b
inet addr:192.168.7.2 Bcast:192.168.255.255 Mask:255.255.0.0
inet6 addr: fe80::6a3:16ff:fee1:5d3b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:645 errors:0 dropped:0 overruns:0 frame:0
TX packets:492 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:74285 (72.5 KiB) TX bytes:98066 (95.7 KiB)
usb1 Link encap:Ethernet HWaddr 04:a3:16:e1:5d:3e
inet addr:192.168.6.2 Bcast:192.168.6.3 Mask:255.255.255.252
inet6 addr: fe80::6a3:16ff:fee1:5d3e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:126 errors:0 dropped:0 overruns:0 frame:0
TX packets:61 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:39046 (38.1 KiB) TX bytes:13030 (12.7 KiB)
表用法示例:
export const SORT_ORDER = {
ASC: "ascending",
DESC: "descending",
OTHER: "other"
};
class TableRow extends React.Component {
render() {
return (
<tr>
{this.props.children}
</tr>
);
}
}
class TableHeader extends React.Component {
constructor(props) {
super(props);
this.sortIcon = new Map([
[SORT_ORDER.ASC, {icon: sortAsc, title: "Ascending"}],
[SORT_ORDER.DESC, {icon: sortDesc, title: "Descending"}],
[SORT_ORDER.OTHER, {icon: sortOther, title: "Unsorted"}]
]);
}
render() {
const {children, onClick, sortOrder} = this.props;
return (
<th>
{onClick ? (
<a href="#" aria-sort={sortOrder} onClick={onClick}>
<img src={this.sortIcon.get(sortOrder).icon} title={this.sortIcon.get(sortOrder).title} />
{children}
</a>
) : children}
</th>
);
}
}
export default class Table extends React.Component {
constructor(props) {
super(props);
this.state = {
sortField: props.defaultSortColumn,
sortOrder: props.defaultSortOrder
};
}
retrieveOrder = (columnId) => {
return columnId === this.state.sortField ? this.state.sortOrder : SORT_ORDER.OTHER;
};
nextOrder = (current) => {
if (current === SORT_ORDER.DESC) {
return SORT_ORDER.ASC;
} else if (current === SORT_ORDER.ASC) {
return SORT_ORDER.DESC;
} else {
return this.props.defaultSortOrder;
}
};
sortedRows = () => {
let descriptor = this.props.structure.find(d => d.attribute === this.state.sortField);
let values = this.props.value.slice();
let orderFactor = this.state.sortOrder === SORT_ORDER.ASC ? 1 : -1;
return values.sort((a, b) => {
let first;
let second;
// null and undefined values should be changed to empty string
if (typeof a[descriptor.attribute] === "number" || typeof b[descriptor.attribute] === "number") {
first = a[descriptor.attribute] || "";
second = b[descriptor.attribute] || "";
} else {
first = descriptor.render(a) || "";
second = descriptor.render(b) || "";
}
return first > second ? orderFactor : first < second ? -orderFactor : 0;
});
};
renderHeaders = () => {
return this.props.structure.map((descriptor, id) => {
let header;
if (this.props.sortable) {
const order = this.retrieveOrder(descriptor.attribute);
const nextOrder = this.nextOrder(order);
header = (
<TableHeader key={id} onClick={() => {this.setState({sortField: descriptor.attribute, sortOrder: nextOrder})}}
sortOrder={order}>
{descriptor.label}
</TableHeader>
)
} else {
header = (
<TableHeader key={id}>
{descriptor.label}
</TableHeader>
)
}
return header;
});
};
renderRows = () => {
const Row = this.props.customRow || TableRow;
const values = this.props.sortable ? this.sortedRows() : this.props.value;
return values.map((value, idx) => (
<Row key={idx} value={value}>
{this.props.structure.map((descriptor, id) => (
<td key={id}>
descriptor.render(value, idx)
</td>
))}
</Row>
));
};
render() {
return (
<table className={this.props.className}>
<thead>
<tr>
{this.renderHeaders()}
</tr>
</thead>
<tbody>
{this.renderRows()}
</tbody>
</table>
);
}
}