首页 > 解决方案 > 从渲染方法中取出分页(React)

问题描述

我在我的 Reactjs 网站中实现了一个基本的分页功能。

我遇到的问题是我在渲染函数中创建了它,所以除非刷新页面,否则它通常不会出现。

我不确定如何在不做不安全的事情(例如使重要变量全局化)的情况下解决此问题。

这是我处理页面分页的渲染函数。


  render() {
    // Logic for displaying current todos
    const indexOfLastTodo = this.state.currentPage * this.state.todosPerPage;
    const indexOfFirstTodo = indexOfLastTodo - this.state.todosPerPage;
    const currentTodos = results.slice(indexOfFirstTodo, indexOfLastTodo);

    const pageNumbers = [];
    for (
      let i = 1;
      i <= Math.ceil(this.state.amountOfWorkstations / this.state.todosPerPage);
      i++
    ) {
      pageNumbers.push(i);
    }

    console.log(this.state.questions);
    if (!this.state.FullDetailsPageToken) {
      if (this.state.questions.length) {
        return (
          <div>
            <h2 style={{ textAlign: "center" }}>
              Completed Workstation Assessments
            </h2>
            <ul>
              <button disabled className="btn btn-secondary">
                Workstation Assessments
              </button>
              <Link to="./admin-center">
                <button className="btn btn-secondary">Edit Questions</button>
              </Link>
              <Link to="./admin-center-view-users">
                <button className="btn btn-secondary">View Users</button>
              </Link>
              <DropdownButton
                style={{ float: "right" }}
                id="dropdown-basic-button"
                title="Completed"
              >
                <Dropdown.Item>
                  {" "}
                  <Link to="admin-view-workstation-assessments-declined">
                    In Progress
                  </Link>
                </Dropdown.Item>
              </DropdownButton>{" "}
            </ul>

            <ul>
              {currentTodos.map(function(r, index) {
                return (
                  <div className="jumbotron">
                    <Questions
                      workStation={r.AssignedWorkstation}
                      date={r.Date}
                      completeToken={r.QuestionStatus}
                      RUId={r.RUId}
                      WSAId={r.WSAId}
                    ></Questions>
                  </div>
                );
              })}
              <div
                style={{ userSelect: "none", cursor: "pointer" }}
                id="page-numbers"
              >
                {pageNumbers.map(number => {
                  return (
                    <button
                      className="btn btn-primary"
                      key={number}
                      id={number}
                      onClick={this.handleClick}
                    >
                      {number}
                    </button>
                  );
                })}
              </div>
            </ul>
          </div>
        );
      } else if (!this.state.questions.length) {
        return (
          <>
            {" "}
            <div>
              <h2 style={{ textAlign: "center" }}>
                Completed Workstation Assessments
              </h2>

              <ul>
                <br />
                <br />{" "}
                <div>
                  <h6> </h6>
                </div>
                <div className="jumbotron">
                  <li style={{ textAlign: "center" }}>
                    <b>no completed Workstation Self-Assessments</b>{" "}
                  </li>
                </div>
              </ul>
            </div>
          </>
        );
      }
    }
  }
}

这是全班

class AdminWorkstations extends React.Component {
  constructor() {
    super();

    this.state = {
      questions: [],
      viewDetails: false,

      currentPage: 1,
      todosPerPage: 10,
      pageNumbers: [],
      FullDetailsPageToken: false
    };
    this.getQuestionByUniqueDate = this.getQuestionByUniqueDate.bind(this);
    // this.test = this.test.bind(this);
  }
  // sets the questions form sql into state for questions
  handleClick = event => {
    this.setState({
      currentPage: Number(event.target.id)
    });
  };

  handlePageChange(pageNumber) {
    this.setState({ activePage: pageNumber });
  }

  componentDidMount() {
    fetch(`/admin-completed-workstations`)
      .then(recordset => recordset.json())
      .then(results => {
        this.setState({ questions: results.recordset });
        console.log(`QuestionResponses array ${this.state.questions}`);

        this.state.questions &&
          this.getQuestionByUniqueDate(this.state.questions);
      });
  }

  getQuestionByUniqueDate(questions) {
    for (var i = 0; i < questions.length; i++) {
      if (
        !results.find(q => q.Date == questions[i].Date) ||
        !results.find(
          q => q.AssignedWorkStation == questions[i].AssignedWorkStation
        )
      ) {
        results.push(questions[i]);
        this.setState({ amountOfWorkstations: results.length });
      }
    }
  }

  render() {
    // Logic for displaying current todos
    const indexOfLastTodo = this.state.currentPage * this.state.todosPerPage;
    const indexOfFirstTodo = indexOfLastTodo - this.state.todosPerPage;
    const currentTodos = results.slice(indexOfFirstTodo, indexOfLastTodo);

    const pageNumbers = [];
    for (
      let i = 1;
      i <= Math.ceil(this.state.amountOfWorkstations / this.state.todosPerPage);
      i++
    ) {
      pageNumbers.push(i);
    }

    console.log(this.state.questions);
    if (!this.state.FullDetailsPageToken) {
      if (this.state.questions.length) {
        return (
          <div>
            <h2 style={{ textAlign: "center" }}>
              Completed Workstation Assessments
            </h2>
            <ul>
              <button disabled className="btn btn-secondary">
                Workstation Assessments
              </button>
              <Link to="./admin-center">
                <button className="btn btn-secondary">Edit Questions</button>
              </Link>
              <Link to="./admin-center-view-users">
                <button className="btn btn-secondary">View Users</button>
              </Link>
              <DropdownButton
                style={{ float: "right" }}
                id="dropdown-basic-button"
                title="Completed"
              >
                <Dropdown.Item>
                  {" "}
                  <Link to="admin-view-workstation-assessments-declined">
                    In Progress
                  </Link>
                </Dropdown.Item>
              </DropdownButton>{" "}
            </ul>

            <ul>
              {currentTodos.map(function(r, index) {
                return (
                  <div className="jumbotron">
                    <Questions
                      workStation={r.AssignedWorkstation}
                      date={r.Date}
                      completeToken={r.QuestionStatus}
                      RUId={r.RUId}
                      WSAId={r.WSAId}
                    ></Questions>
                  </div>
                );
              })}
              <div
                style={{ userSelect: "none", cursor: "pointer" }}
                id="page-numbers"
              >
                {pageNumbers.map(number => {
                  return (
                    <button
                      className="btn btn-primary"
                      key={number}
                      id={number}
                      onClick={this.handleClick}
                    >
                      {number}
                    </button>
                  );
                })}
              </div>
            </ul>
          </div>
        );
      } else if (!this.state.questions.length) {
        return (
          <>
            {" "}
            <div>
              <h2 style={{ textAlign: "center" }}>
                Completed Workstation Assessments
              </h2>

              <ul>
                <br />
                <br />{" "}
                <div>
                  <h6> </h6>
                </div>
                <div className="jumbotron">
                  <li style={{ textAlign: "center" }}>
                    <b>no completed Workstation Self-Assessments</b>{" "}
                  </li>
                </div>
              </ul>
            </div>
          </>
        );
      }
    }
  }
}

关于如何在渲染函数中进行此操作或修复代码以便正确渲染分页的任何建议。

谢谢!

编辑---试图改变它来工作,如图所示。仍然没有成功,也没有任何显示。

class AdminWorkstations extends React.Component {
  constructor() {
    super();

    this.state = {
      questions: [],
      viewDetails: false,

      currentPage: 1,
      todosPerPage: 10,
      pageNumbers: [],
      // FullDetailsPageToken: false,
      loadingToken: true,
      indexOfLastTodo: null,
      indexOfFirstTodo: null,
      currentTodos: null,
      currentTodos: null
    };
    this.getQuestionByUniqueDate = this.getQuestionByUniqueDate.bind(this);
    // this.test = this.test.bind(this);
  }
  // sets the questions form sql into state for questions
  handleClick = event => {
    this.setState({
      currentPage: Number(event.target.id)
    });
  };

  handlePageChange(pageNumber) {
    this.setState({ activePage: pageNumber });
  }

  componentDidMount() {
    fetch(`/admin-completed-workstations`)
      .then(recordset => recordset.json())
      .then(results => {
        this.setState({ questions: results.recordset });
        console.log(`QuestionResponses array ${this.state.questions}`);

        this.state.questions &&
          this.getQuestionByUniqueDate(this.state.questions);
      });
    this.state.indexOfLastTodo =
      this.state.currentPage * this.state.todosPerPage;
    this.state.indexOfFirstTodo =
      this.state.indexOfLastTodo - this.state.todosPerPage;
    this.state.currentTodos = results.slice(
      this.state.indexOfFirstTodo,
      this.state.indexOfLastTodo
    );

    const pageNumbers = [];
    for (
      let i = 1;
      i <= Math.ceil(this.state.amountOfWorkstations / this.state.todosPerPage);
      i++
    ) {
      pageNumbers.push(i);
    }
  }

  getQuestionByUniqueDate(questions) {
    for (var i = 0; i < questions.length; i++) {
      if (
        !results.find(q => q.Date == questions[i].Date) ||
        !results.find(
          q => q.AssignedWorkStation == questions[i].AssignedWorkStation
        )
      ) {
        results.push(questions[i]);
        this.setState({ amountOfWorkstations: results.length });
      }
    }
    this.setState({ loadingToken: false });
  }

  render() {
    // Logic for displaying current todos
    // const indexOfLastTodo = this.state.currentPage * this.state.todosPerPage;
    // const indexOfFirstTodo = indexOfLastTodo - this.state.todosPerPage;
    // const currentTodos = results.slice(indexOfFirstTodo, indexOfLastTodo);

    // const pageNumbers = [];
    // for (
    //   let i = 1;
    //   i <= Math.ceil(this.state.amountOfWorkstations / this.state.todosPerPage);
    //   i++
    // ) {
    //   pageNumbers.push(i);
    // }

    console.log(this.state.questions);

    if (this.state.questions.length && !this.state.loadingToken) {
      return (
        <div>
          <h2 style={{ textAlign: "center" }}>
            Completed Workstation Assessments
          </h2>

          <ul>
            <button disabled className="btn btn-secondary">
              Workstation Assessments
            </button>
            <Link to="./admin-center">
              <button className="btn btn-secondary">Edit Questions</button>
            </Link>
            <Link to="./admin-center-view-users">
              <button className="btn btn-secondary">View Users</button>
            </Link>
            <DropdownButton
              style={{ float: "right" }}
              id="dropdown-basic-button"
              title="Completed"
            >
              <Dropdown.Item>
                {" "}
                <Link to="admin-view-workstation-assessments-declined">
                  In Progress
                </Link>
              </Dropdown.Item>
            </DropdownButton>{" "}
          </ul>

          <ul>
            {this.state.currentTodos.map(function(r, index) {
              return (
                <div className="jumbotron">
                  <Questions
                    workStation={r.AssignedWorkstation}
                    date={r.Date}
                    completeToken={r.QuestionStatus}
                    RUId={r.RUId}
                    WSAId={r.WSAId}
                  ></Questions>
                </div>
              );
            })}
            <div
              style={{ userSelect: "none", cursor: "pointer" }}
              id="page-numbers"
            >
              {this.state.pageNumbers.map(number => {
                return (
                  <button
                    className="btn btn-primary"
                    key={number}
                    id={number}
                    onClick={this.handleClick}
                  >
                    {number}
                  </button>
                );
              })}
            </div>
          </ul>
        </div>
      );
    } else if (!this.state.questions.length && !this.state.loadingToken) {
      return (
        <>
          {" "}
          <div>
            <h2 style={{ textAlign: "center" }}>
              Completed Workstation Assessments
            </h2>

            <ul>
              <br />
              <br />{" "}
              <div>
                <h6> </h6>
              </div>
              <div className="jumbotron">
                <li style={{ textAlign: "center" }}>
                  <b>no completed Workstation Self-Assessments</b>{" "}
                </li>
              </div>
            </ul>
          </div>
        </>
      );
    } else if (this.state.loadingToken) {
      return (
        <>
          <h2 style={{ textAlign: "center" }}>
            Completed Workstation Assessments
          </h2>
          <div style={{ textAlign: "center" }}>LOADING</div>
        </>
      );
    }
  }
}

编辑 -

添加了课程的最新更新。结果显示,但分页不起作用。

class AdminWorkstations extends React.Component {
  constructor() {
    super();

    this.state = {
      questions: [],
      viewDetails: false,

      currentPage: 1,
      todosPerPage: 10,
      pageNumbers: [],
      // FullDetailsPageToken: false,
      loadingToken: true
    };
    this.getQuestionByUniqueDate = this.getQuestionByUniqueDate.bind(this);
    // this.test = this.test.bind(this);
  }
  // sets the questions form sql into state for questions
  handleClick = event => {
    this.setState(
      {
        currentPage: Number(event.target.id)
      },
      () => this.updatePages()
    );
  };

  handlePageChange(pageNumber) {
    this.setState({ activePage: pageNumber });
  }

  updatePages() {
    // Logic Added Here
    const indexOfLastTodo = this.state.currentPage * this.state.todosPerPage;
    const indexOfFirstTodo = indexOfLastTodo - this.state.todosPerPage;
    this.setState({
      currentTodos: results.slice(indexOfFirstTodo, indexOfLastTodo)
    });
    // Saved the currentTodos value inside the state.
    for (
      let i = 1;
      i <= Math.ceil(this.state.amountOfWorkstations / this.state.todosPerPage);
      i++
    ) {
      // Saved the pageNumbers value inside the state
      this.setState({
        pageNumbers: [...this.state.pageNumbers, i]
      });
    }
  }

  componentDidMount() {
    fetch(`/admin-completed-workstations`)
      .then(recordset => recordset.json())
      .then(results => {
        this.setState({ questions: results.recordset });
        console.log(`QuestionResponses array ${this.state.questions}`);

        this.state.questions &&
          this.getQuestionByUniqueDate(this.state.questions);
      });
    this.updatePages();
  }

  getQuestionByUniqueDate(questions) {
    for (var i = 0; i < questions.length; i++) {
      if (
        !results.find(q => q.Date == questions[i].Date) ||
        !results.find(
          q => q.AssignedWorkStation == questions[i].AssignedWorkStation
        )
      ) {
        results.push(questions[i]);
        this.setState({ amountOfWorkstations: results.length });
      }
    }
    this.setState({ loadingToken: false });
  }

  render() {
    // const indexOfLastTodo = this.state.currentPage * this.state.todosPerPage;
    // const indexOfFirstTodo = indexOfLastTodo - this.state.todosPerPage;
    // const currentTodos = results.slice(indexOfFirstTodo, indexOfLastTodo);

    // const pageNumbers = [];
    // for (
    //   let i = 1;
    //   i <= Math.ceil(this.state.amountOfWorkstations / this.state.todosPerPage);
    //   i++
    // ) {
    //   pageNumbers.push(i);
    // }

    // console.log(this.state.questions);

    if (this.state.questions.length && !this.state.loadingToken) {
      return (
        <div>
          <PageTitle />

          <ul>
            <button disabled className="btn btn-secondary">
              Workstation Assessments
            </button>
            <Link to="./admin-center">
              <button className="btn btn-secondary">Edit Questions</button>
            </Link>
            <Link to="./admin-center-view-users">
              <button className="btn btn-secondary">View Users</button>
            </Link>
            <DropdownButton
              style={{ float: "right" }}
              id="dropdown-basic-button"
              title="Completed"
            >
              <Dropdown.Item>
                {" "}
                <Link to="admin-view-workstation-assessments-declined">
                  In Progress
                </Link>
              </Dropdown.Item>
            </DropdownButton>{" "}
          </ul>

          <ul>
            {this.state.currentTodos.map(function(r, index) {
              return (
                <div className="jumbotron">
                  <Questions
                    workStation={r.AssignedWorkstation}
                    date={r.Date}
                    completeToken={r.QuestionStatus}
                    RUId={r.RUId}
                    WSAId={r.WSAId}
                  ></Questions>
                </div>
              );
            })}
            <div
              style={{ userSelect: "none", cursor: "pointer" }}
              id="page-numbers"
            >
              {this.state.pageNumbers.map(number => {
                return (
                  <button
                    className="btn btn-primary"
                    key={number}
                    id={number}
                    onClick={this.handleClick}
                  >
                    {number}
                  </button>
                );
              })}
            </div>
          </ul>
        </div>
      );
    } else if (!this.state.questions.length && !this.state.loadingToken) {
      return (
        <>
          {" "}
          <div>
            <PageTitle />

            <ul>
              <br />
              <br />{" "}
              <div>
                <h6> </h6>
              </div>
              <div className="jumbotron">
                <li style={{ textAlign: "center" }}>
                  <b>no completed Workstation Self-Assessments</b>{" "}
                </li>
              </div>
            </ul>
          </div>
        </>
      );
    } else if (this.state.loadingToken) {
      return (
        <>
          <PageTitle />
          <div style={{ textAlign: "center" }}>LOADING</div>

          <div className="loader center">
            <i className="fa fa-cog fa-spin" />
          </div>
        </>
      );
    }
  }
}

标签: javascriptreactjs

解决方案


这是一个如何实现分页组件的示例:

const Pagination = ({
  onChange,
  total,
  pageSize,
  current,
}) => {
  return React.useMemo(() => {
    const pages = [
      ...new Array(Math.ceil(total / pageSize)),
    ].map((_, index) => index + 1);
    if (pages.length === 1) {
      //do not display if there is only one page
      return '';
    }
    return (
      <label>
        page
        <select
          onChange={e => onChange(e.target.value)}
          value={current}
        >
          {pages.map(page => (
            <option key={page} value={page}>
              {page}
            </option>
          ))}
        </select>
      </label>
    );
  }, [current, onChange, pageSize, total]);
};
const Item = React.memo(function Item({ item }) {
  return <li>{item}</li>;
});
const List = React.memo(function List({ items }) {
  return (
    <ul>
      {items.map(item => (
        <Item key={item} item={item} />
      ))}
    </ul>
  );
});
const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const App = () => {
  const [page, setPage] = React.useState(1);
  const [itemsPerPage, setItemsPerPage] = React.useState(2);
  const changeItemsPerPage = React.useCallback(e => {
    setItemsPerPage(e.target.value);
    setPage(1); //reset page to 1
  }, []);
  const changePage = React.useCallback(
    page => setPage(Number(page)),
    []
  );
  const items = React.useMemo(
    () =>
      data.slice(
        (page - 1) * itemsPerPage,
        page * itemsPerPage
      ),
    [itemsPerPage, page]
  );
  return (
    <div>
      <div>
        <label>
          items per page
          <select
            value={itemsPerPage}
            onChange={changeItemsPerPage}
          >
            {[2, 3, 5, 6, 9, 10, 11].map(p => (
              <option value={p} key={p}>
                {p}
              </option>
            ))}
          </select>
        </label>
      </div>
      <div>
        <Pagination
          onChange={changePage}
          total={data.length}
          pageSize={itemsPerPage}
          current={page}
        />
      </div>
      <div>
        <List items={items}></List>
      </div>
    </div>
  );
};

//render app
ReactDOM.render(
  <App />,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>


推荐阅读