使用asc / desc和默认排序对列进行排序

时间:2016-12-29 23:20:06

标签: sorting reactjs redux

我的表格中有多列,例如:

id | name | amount | description

我想对每一列进行排序 - 在第一次点击时按升序排列,按第二次按降序排序,第三次按照默认值重新排序,然后重新进行排序。

默认值是以asc顺序提取的id列。

因此,reducer中的默认状态是:

sort: {
    key: 'id',
    desc: false
}

点击名称列的后续步骤将是:

sort: {
    key: 'name',
    desc: false
}

sort: {
    key: 'name',
    desc: true
}

sort: {
    key: 'id',
    desc: false
}

视图使用列的名称作为参数调用操作:

<td onClick={() => this.props.sort('name')}>Name</td>
<td onClick={() => this.props.sort('amount')}>Amount</td>

操作应发送此类keydesc值,以便与我的模式匹配:

export function sort(key) {
    return dispatch => {

    };
};

我该怎么做?

1 个答案:

答案 0 :(得分:1)

在这里,您可以在代码示例中进行简要说明。 我只设置了2列,因为我很懒,抱歉。

小提琴:https://jsfiddle.net/u1wru0gb/1/

const data = [
    { id: 1, name: 'Bruce' },
    { id: 3, name: 'Martin' },
    { id: 2, name: 'Andrew' },
];

/**
 * Nothing interesting, just render...
 */
function Table({ data, sortByKey }) { 
    const renderRow = ({ id, name }, idx) => (
        <tr key={idx}>
            <td>{id}</td>
            <td>{name}</td>
        </tr>
    )

    return (
        <table>
            <tr>
                <th onClick={sortByKey('id')}>ID</th>
                <th onClick={sortByKey('name')}>Name</th>
            </tr>
            { data.map(renderRow) }
        </table>
    );
}

class Container extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            sort: {
                key: undefined,
                // 0 - not ordering
                // 1 - asc
                // 2 - desc
                order: 0,
            },
        };

        this.sortByKey = this.sortByKey.bind(this);
    }

    sortedData() {
        const { key, order } = this.state.sort;

        // Only sort if key is provided & order != 0.
        if (key && order) {
            // Comparison function for "asc" sorting.
            function compare(a, b) {
                if (a[key] < b[key]) return -1;
                if (a[key] > b[key]) return 1;
                return 0;
            }

            // Attention! Sort mutates array, clone first.
            return [...this.props.data].sort((a, b) => {
                // Interesting part. Sort in "asc" order. Flip if want "desc" order!
                return compare(a, b) * (order === 1 ? 1 : -1);
            });
        }

        // Return original data (order = 0)
        return this.props.data;
    }

    sortByKey(key) {
        return () => {
            const sort = (this.state.sort.key === key)
                // Key matches, update order
                ? { key, order: (this.state.sort.order + 1) % 3 }
                // Key differs, start with "asc" order
                : { key, order: 1 };
            this.setState({ sort });
        }
    }

    render() {
        return (
            <Table data={this.sortedData()} sortByKey={this.sortByKey} />
        );
    }
}

ReactDOM.render(
    <Container data={data} />,
    document.getElementById('container')
);