gpt4 book ai didi

javascript - 用 React 实现可排序表的正确方法是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:40:26 24 4
gpt4 key购买 nike

我当前的实现:

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是一个改变父组件状态的函数=>它改变了表的值。我还有defaultSortColumndefaultSortOrder表格填满后进行排序。

问题是我的表可以在页面声明多次。

所以,

1) 我无法以其状态存储表值。我应该吗?

2) 如何在不使用 componentDidMount 的情况下实现默认排序?使用当前实现默认排序只发生一次,当 componentDidMount被调用,但我有超过 1 个 <Table/>页面上的组件。我试过使用 componentWillReceiveProps函数,但当我更改 <Table/> 时它也会被调用状态 sort功能。所以我不能使用它。

最佳答案

我最终的解决方案是:

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>
);
}
}

表格用法示例:

            this.tableStructure = [
{
attribute: "number", label: "Row Number"
render: (row) => {return row.number}
},
{
attribute: "created", label: "Creation time"
render: (row) => {return this.dateToString(row.created)}
},
{
attribute: "type", label: "Row Type"
render: (row) => {return row.type}
},
{
attribute: "state", label: "State",
render: (row) => {return row.state}
},
{
attribute: "action", label: "Action"
render: (row) => {
return (
<button onClick={this.doSomething}>
</button>
);
}
}
];

<Table structure={this.tableStructure} value={this.state.someValue} sortable
defaultSortColumn="created" defaultSortOrder={SORT_ORDER.DESC} />

实现基于http://styleguide.cfapps.io/react_base_tables.html

关于javascript - 用 React 实现可排序表的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43427232/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com