简体   繁体   English

为什么排序在 React 组件中不起作用

[英]Why does sort not work in React component

I have this array of rows that I try to sort alphabetically with the sortByTitle() function.我有这个行数组,我尝试使用 sortByTitle() function 按字母顺序排序。 The sort method I am pretty sure is OK but there must be something with where I am calling it that makes it not work and it does not mutate the array at all.我很确定排序方法是可以的,但是我在调用它的地方肯定有一些东西使它不起作用并且它根本不会改变数组。 It may be because of the lifecycle of react.这可能是因为反应的生命周期。

The sort on getRows() works perfectly. getRows() 上的排序非常有效。

  getHistory() {
    if (this.state.historyUser && this.state.historyUser.length) {
      return this.state.historyUser.map(x => {
        x.state = x.finishDate ? 'closed' : 'open';
        return x;
      });
    } else {
      return [];
    }
  }

  getRows() {
    let rows = this.state.rows || this.getHistory();
    rows.sort((a, b) => b.creationDate - a.creationDate)
    return rows.map((x, j) => {
      return (
        <div key={j} className={`testTable__row testTable__test testTable__test--${x.state}`}>
          {this.allTypes.map((type, i) => {
            let value = type.className !== 'checks' ? x[type.prop] : x.checked;
            if (type.className === 'name') {
              value = (
                <a href={`/test/${x._id}#1`}>{x[type.prop]}</a>
              );
            }
            return (
              <CellUser
                key={i}
                id={x._id}
                value={value}
                className={type.className}
                changeChecked={this.changeChecked}
                isSimulacro={x.isSimulacro}
                score={x.scoreProMIR}
              />
            );
          })}
        </div>
      );
    });
  }

  handleInputChange(e) {
    let rows = this.state.historyUser;
    const selector = e.target.getAttribute("label")
    rows = rows.filter(elm => elm[selector].toLowerCase().includes(e.target.value.toLowerCase()));
    this.setState({ inputValue: e.target.value, rows: rows});
  }

  sortByTitle() {
    let rows = this.state.rows || this.getHistory();
    rows.sort((a, b) => a.title.localeCompare(b.title));
    this.setState({ rows: row });
  }

  render() {
    return (
      <div style={{ height: '100%', width: '100%' }}>
        <div className="testTable">
          <div className="testTable__row testTable__header">
            <div className="testTable__column testTable__column--name"> 
              Nombre 
              <input type="text" label="title" onChange={this.handleInputChange} />
              <button onClick={this.sortByTitle}> Ordenar </button>
            </div>
            <div className="testTable__column testTable__column--score"> Nota </div>
            <div className="testTable__column testTable__column--type"> Tipo </div>
            <div className="testTable__column testTable__column--date"> Fecha </div>
            <div className="testTable__column testTable__column--state"> Estado </div>
            <div className="testTable__column testTable__column--checks">
              <label>
                Abiertos <Checkbox selected={this.state.checkOpen} onClick={this.allOpened} />
              </label>
              <label>
                Cerrados <Checkbox selected={this.state.checkClose} onClick={this.allClosed} />
              </label>
              <label>
                Todos <Checkbox selected={this.state.selectedAllRows} onClick={this.allRows} />
              </label>
            </div>
          </div>
          <div className="testTable__body">
            <Scrollbars {...scrollbarsProps()}>{this.getRows()}</Scrollbars>
          </div>

          <div
            className={`testTable__row testTable__footer${
              this.state.btnClose || this.state.btnReset || this.state.btnReopen ? ' active' : ''
            }`}
          >
            <ReactCSSTransitionGroup
              component="div"
              transitionName="topBottom"
              transitionEnterTimeout={0}
              transitionLeaveTimeout={0}
            >
              {this.state.btnClose ? (
                <button className="button button--close" onClick={this.requestAction} name="close">
                  Cerrar seleccionados
                </button>
              ) : null}
              {this.state.btnReset ? (
                <button className="button button--reset" onClick={this.requestAction} name="reset">
                  Resetear seleccionados
                </button>
              ) : null}
              {this.state.btnReopen ? (
                <button className="button button--open" onClick={this.requestAction} name="open">
                  Reabrir seleccionados
                </button>
              ) : null}
              {this.state.btnAddToStats ? (
                <button className="button button--add" onClick={this.requestAction} name="add">
                  Añadir a estadísticas
                </button>
              ) : null}
            </ReactCSSTransitionGroup>
          </div>
        </div>
        <ReactCSSTransitionGroup
            component="div"
            transitionName="topBottom"
            className={`superCoverMsg${this.state.confirmAction ? '' : ' none'}`}
            transitionEnterTimeout={0}
            transitionLeaveTimeout={0}
          >
            {this.state.confirmAction ? (
              <div className="coverMsg confirmPopUp" key="0">
                <p>{this.state.textAction}</p>
                <div className="coverLabelInput coverLabelInput__botones columnWidth">
                  <ul className="cien">
                    <li className="cincuenta cancelar">
                      <a onClick={this.removeConfirmAction} href="#" title="Cancelar">
                        Cancelar
                      </a>
                    </li>
                    <li className="cincuenta aceptar">
                      <a onClick={this.aceptAction} href="#" title="Aceptar">
                        Aceptar
                      </a>
                    </li>
                  </ul>
                </div>
              </div>
            ) : null}
          </ReactCSSTransitionGroup>
      </div>
    );
  }
}

It looks like your setting rows equal to row, which I don't see defined.看起来您的设置行等于行,我没有看到定义。 Maybe change this也许改变这个

 this.setState({ rows: row });

to

 this.setState({ rows: rows });

Also I think the react-friendly way to modify an array from state would be use a spread operator so as not to mutate the state object directly, like so:此外,我认为从 state 修改数组的反应友好方法是使用扩展运算符,以免直接改变 state object,如下所示:

 let rows = [...this.state.rows] || this.getHistory();

sortByTitle() {
    let rows = this.state.rows || this.getHistory();
    rows.sort((a, b) => a.title.localeCompare(b.title));
    this.setState({ rows: row });
}

You are mutating the state.您正在变异 state。 instead copy the content into separate new array, sort it and use that new variable in .setState .而是将内容复制到单独的新数组中,对其进行排序并在.setState中使用该新变量。

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

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