复选框和新组件,无法正常工作

时间:2020-08-15 21:48:53

标签: javascript reactjs bootstrap-4

您好,我正在尝试使用复选框的数据构建一个新组件,为此,我有以下代码:

import React from "react";
import BottomScrollListener from "react-bottom-scroll-listener";
import ThingsQuery from "./../querys/ThingsQuery";
import "./styles/Things.scss";

export default class Things extends React.Component {
  constructor() {
    super();
    this.displayData = [this.createPag()];
  }

  state = {
    sort: "popular",
    page: 1,
    featured: false,
    allPages: false,
  };

  createPag = (onNull = () => {}) => {
    return (
      <ThingsQuery
        page={this.state.page}
        sort={this.state.sort}
        featured={this.state.featured}
        onNull={onNull}
      />
    );
  };

  handleSortClick = (e) => {
    const sort = e.target.innerText.trim().toLowerCase();
    this.setState({ sort, page: 1, allPages: false }, () => {
      this.displayData = [this.createPag()];
    });
  };

  changePage = () => {
    if (!this.state.allPages) {
      const currentPage = this.state.page + 1;
      this.setState({ page: currentPage });
      const page = this.createPag(() => {
        this.setState({ allPages: true });
      });
      if (!this.state.allPages) {
        this.displayData.push(page);
      }
    }
  };

  handleChangeFeatured = (e) => {
    const featured = e.target.checked;
    console.log("onChangeFeatured");
    console.log(featured);
    this.setState({ page: 1, allPages: false, featured: featured }, () => {
      console.log("State changed");
      this.displayData = [this.createPag()];
    });
  };

  render() {
    return (
      <div className="things col-xs-1 text-center">
        <BottomScrollListener onBottom={this.changePage} />
        <div>
          <div className="custom-control custom-switch">
            <input
              onChange={this.handleChangeFeatured}
              type="checkbox"
              className="custom-control-input"
              id="customSwitch1"
              checked={this.state.featured}
            />
            <label className="custom-control-label" for="customSwitch1">
              Featured
            </label>
          </div>
          <div className="btn-group" role="group" aria-label="Basic example">
            <button
              onClick={this.handleSortClick}
              type="button"
              className="btn btn-secondary"
            >
              Popular
            </button>
            <button
              onClick={this.handleSortClick}
              type="button"
              className="btn btn-secondary"
            >
              Newest
            </button>
            <button
              onClick={this.handleSortClick}
              type="button"
              className="btn btn-secondary"
            >
              Latest
            </button>
          </div>
          <div className="container">
            <div className="card-columns">{this.displayData}</div>
          </div>
        </div>
      </div>
    );
  }
}

如您所见,我有一个checkBox,其检查值由state.featured获取。

这可以正确加载如果我输入代码featured=True,请加载该文件,如果我也输入了错误的作品,则该文件。

问题是当尝试在浏览器上更改值时。

当我确实单击开关时,此更改以及值也更改了,createPag被完全执行,但是<ThingsQuery .... />在第一次单击时不起作用,我需要更改检查值2次,当然,此后,我得到了想要的相反数据。

我怎么解决这个问题,为什么<ThingsQuery.../>第一次单击时不运行?

谢谢

1 个答案:

答案 0 :(得分:0)

存储为局部实例变量的值(即this.displayData)在更改时不会引起重新渲染。它们必须处于状态,并通过setState进行更改,以使更改触发重新渲染。

因此,在您的情况下,您呼叫setState来更改sortallPages,然后在 之后更改状态并随后重新呈现,然后进行更改this.displayData中的setState回调中。由于重新渲染已经完成,并且更改本地实例变量不会导致重新渲染,因此在下次运行之前,setState都会使用该新的displayData进行重新渲染,因此不会进行任何更改。

如果您希望this.displayData中的更改引起重新渲染,则它应该处于状态。影响所呈现内容的任何值都应处于状态。

相关问题