javascript - 从渲染方法中取出分页(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>
</>
);
}
}
}
解决方案
这是一个如何实现分页组件的示例:
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>
推荐阅读
- python - 在 flask-sqlalchemy 中计算当天的总发生次数
- javascript - Javascript正则表达式:重复非捕获组
- java - 如何用最后一行更改二维数组的第一行?
- google-maps - 带有单个蜂窝塔的 Google Maps Geolocation API 经常返回“找不到错误 404 地理位置”
- reactjs - 使用 CookPete/react-player 从 S3 播放 HLS 视频
- macos - gsed:递归查找、递增和替换
- python - Python 下溢应该不太精确
- cmake - 使用 QtCreator 和 CMAKE 构建 helloworld GUI
- webpack - 我使用了 webpack,但为什么请求没有减少?
- python - 素数练习