繁体   English   中英

React:如何通过多个元素的单个引用替换.querySelectorAll

[英]React: How to replace .querySelectorAll by single refs for multiple elements

单击表格标题时,我想对表格行进行排序。 我的代码在此处处理常规的 html/javascript 片段。 但是它不能作为 React 方法工作。 我认为问题在于使用.querySelectorAll().parentNode方法。 我已经用this.refs.rows替换了.getElementById()方法,方法是向<tbody>添加一个引用,但我认为一个引用不能指向多个元素(以获取所有<td>元素)。 我正在寻找一种类似的方法来替换这两种似乎不起作用的方法。 还是完全是另一个问题?


编辑:按照评论中的要求添加了整个 React 组件

import React from "react";

import { Row, Col, Table } from "reactstrap";

export class ComparePlayers extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            players: [],
        };
    }

    componentDidMount() {
        fetch("/players")
            .then((response) => response.json())
            .then((state) => {
                this.setState({ players: state });
            });
    }

    handleSort(n) {
        let rows, switching, i, x, y, shouldSwitch;
        switching = true;
        while (switching) {
            switching = false;
            rows = this.refs.rows; /* replaced document.getElementById("myTable").rows; */
            for (i = 0; i < rows.length; i++) {
                shouldSwitch = false;
                x = rows[i].querySelectorAll("td")[n]; // how to replace?
                y = rows[i + 1].querySelectorAll("td")[n]; // how to replace?
                if (!isNaN(Number(x.innerHTML))) {
                    if (Number(x.innerHTML) > Number(y.innerHTML)) {
                        shouldSwitch = true;
                        break;
                    }
                } else {
                    if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
                        shouldSwitch = true;
                        break;
                    }
                }
            }
            if (shouldSwitch) {
                rows[i].parentNode.insertBefore(rows[i + 1], rows[i]); // how to replace?
                switching = true;
            }
        }
    }

    render() {
        return (
            <Row>
                <Col>
                    <Table bordered>
                        <thead>
                            <tr>
                                {this.state.players.length > 0 &&
                                    Object.keys(this.state.players[0]).map((key, id) => (
                                        <th
                                            key={"header_" + key}
                                            onClick={() => this.handleSort(id)}
                                        >
                                            {key.toUpperCase()}
                                        </th>
                                    ))}
                            </tr>
                        </thead>
                        <tbody ref="rows">
                            {this.state.players.length > 0 &&
                                this.state.players.map((player, id) => {
                                    return (
                                        <tr key={"row" + id}>
                                            {Object.values(player).map((value) => (
                                                <td key={"table_value_" + value}>{value}</td>
                                            ))}
                                        </tr>
                                    );
                                })}
                        </tbody>
                    </Table>
                </Col>
            </Row>
        );
    }
}

更新和解决方案:

我使用了@MahdyAslamy 的答案并适应了我的 state 这是一个对象数组。 我使用本教程根据属性值对对象数组进行排序。 这是最终代码:

handleSort(el) {
  const compareValues = (key) => {
    return function innerSort(a, b) {
      if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
        // property doesn't exist on either object
        return 0;
      }

      const varA = typeof a[key] === "string" ? a[key].toUpperCase() : a[key];
      const varB = typeof b[key] === "string" ? b[key].toUpperCase() : b[key];

      let comparison = 0;
      if (varA > varB) {
        comparison = 1;
      } else if (varA < varB) {
        comparison = -1;
      }
      return comparison;
    };
  };
  const sorted = this.state.players.sort(compareValues(el));
  this.setState({
    players: sorted
  });
}

通过更改 dom 上的标签 position 来对表进行排序并不是一个好方法。 react 建议使用状态和通常的组件生命周期来改变外观。

例如:

 class Game extends React.Component { constructor(props) { super(props); this.state = { list: [5,6,8,9,6,5,4,22,4] } } render() { return ( <div className="game"> <button onClick={() => this.setState({ list: this.state.list.sort() })}>sort</button> <ul> {this.state.list.map(el => <li>{el}</li>)} </ul> </div> ); } } // ======================================== ReactDOM.render( <Game />, document.getElementById('root') );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

仅对列表进行排序,然后在渲染时显示排序列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM