我陷入了reactJS的新手问题(我上周开始学习)。我正在开发一个单页应用程序,它呈现来自 Google Book API 的搜索结果,一切看起来都很棒,我可以从 api 获取数据(实际上现在我正在使用 AJAX)。
我在过去 8 小时内尝试过的方法都无法更新我的 react-paginate 中的状态。成分。 可能问题出在我的handlePageClick函数中,但是这个模块的文档有点奇怪,加上我对react的不熟悉,这让事情变得更加困难。
这是我的app.js
import React from 'react';
import ReactDOM from 'react-dom';
import { compose } from 'redux';
import {
cloneDeep, findIndex, orderBy, keys, values, transforms
} from 'lodash';
import Bookshelf from './bookshelf.js';
import ReactPaginate from 'react-paginate';
import Header from './layout/header.js';
import Footer from './layout/Footer.js';
import Books from './layout/Books.js';
// import {Paginator, paginate } from './helpers';
const app = document.getElementById('app');
export default class Main extends React.Component{
constructor(props){
super(props);
this.state = {
items:[],
offset:0
};
this.localSubmit = this.localSubmit.bind(this);
this.onPerPage = this.onPerPage.bind(this);
this.handlePageClick = this.handlePageClick.bind(this);
}
localSubmit(search) {
this.setState({items: []});
var component = this;
$.get("https://www.googleapis.com/books/v1/volumes?q=intitle:" + encodeURIComponent(search) + "&printType=books&orderBy=newest&maxResults=39", function (data) {
component.setState(data);
Bookshelf();
$(".front").css("background", "url(../img/no_book_cover.jpg)");
for (var i = 0; i < component.state.items.length; i++) {
if (component.state.items[i].volumeInfo.imageLinks != null) {
$("#book-" + component.state.items[i].id).find(".front").css("background", "url("+ component.state.items[i].volumeInfo.imageLinks.thumbnail +")");
}
}
$(".front").css("background-size", "100% 100%");
$(".front").css("border", "2px solid #eee");
$(".front").css("background-size", "100% 100%");
});
}
handlePageClick(component){
console.log(component);
let selected = component.selected;
let offset = Math.ceil(selected * this.props.perPage);
console.log("the offset is:"+offset)
this.setState({offset: offset}, () => {
// this.localsubmit
});
}
onSelect(page) {
const pages = Math.ceil(
this.state.items.length / 9
);
console.log(pages);
this.setState({
pagination: {
perPage:this.state.pagination,
page: Math.min(Math.max(page, 1), pages)
}
});
}
onPerPage(value) {
this.setState({
pagination: {
page:this.state.pagination,
perPage: parseInt(value, 10)
}
});
}
render () {
const pages = Math.ceil(
this.state.items.length / 9
);
console.log("length:"+this.state.items.length);
console.log(pages);
var books = [];
var content;
books = this.state.items.map(function(book) {
return <Books key={book.id} item={book.volumeInfo} identifier={book.id} />;
});
if (books.length > 0) {
content = books;
} else {
content = <div className="search-icon" ><span className="glyphicon glyphicon-search"></span></div>
}
return (
<div>
<Header localSubmit={this.localSubmit}/>
<div className="main">
<div id="bookshelf" className="bookshelf">
{content}
</div>
<ReactPaginate previousLabel={"previous"}
nextLabel={"next"}
breakLabel={<a href="">...</a>}
breakClassName={"break-me"}
pageCount={this.state.pageCount}
marginPagesDisplayed={2}
pageRangeDisplayed={5}
onPageChange={this.handlePageClick}
containerClassName={"pagination"}
subContainerClassName={"pages pagination"}
activeClassName={"active"} />
</div>
<Footer />
</div>
);
}
}
ReactDOM.render(<Main perPage={10}/>, document.getElementById("app"));
这是另一个相关组件,books 类
import React from "react";
import ReactDOM from 'react-dom';
var Books = React.createClass({
getInitialState : function () {
return ({});
},
componentDidMount : function () {
if (this.props.item != null) {
this.setState(this.props.item);
}
},
render : function () {
var authors = "";
console.log(this.props.item);
if (this.state.authors != null) {
for (var i = 0; i < this.state.authors.length; i++) {
if (i > 1) {
authors = ", " + this.state.authors[i];
} else {
authors = this.state.authors[i];
}
}
}
var descrip = "...";
if (this.state.description != null) {
descrip = this.state.description.substring(0, 180) + "...";
}
var id = "";
if (this.props.identifier != null) {
id = "book-" + this.props.identifier;
}
return (
<figure>
<div className="book" id={id}></div>
<div className="buttons"><a href={this.state.previewLink} target="_blank">Preview</a><a href="#">Details</a></div>
<figcaption><h2>{this.state.title}<span>{authors}</span></h2></figcaption>
<div className="details">
<ul>
<li>{descrip}</li>
<li>{this.state.publishedDate}</li>
<li>{this.state.publisher}</li>
<li>{this.state.pageCount} pages</li>
</ul>
</div>
</figure>
);
}
});
export default Books;
我已经尝试过另一个用于 react 分页的模块,但没有成功,这个看起来更容易,但是缺少一些东西,你们能帮助我吗?
错误:
当我点击下一页时,我得到了这个 Cannot read property 'perPage' of undefined
并且在 page 1
中显示了整个内容,react-paginate 过滤实际上是不工作。
编辑2:
我已经取消注释了构造函数内的 this.handlePageClick = this.handlePageClick.bind(this);
行,但仍然没有过滤器,现在我没有收到任何错误,这正在插入我疯狂=(
提前致谢!
最佳答案
Error: When I click in the next page i got this Cannot read property 'perPage' of undefined and in page 1 the whole content are being displayed, the react-paginate filtering actually it's not working.
您需要绑定(bind)handlePageClick
至this
在构造函数中(该行已注释),就像您对 onPerPage
所做的那样还有另一种方法。
更新后编辑 2 好吧,现在看起来好多了。然而你的代码真的很困惑,我可以清楚地看到你四处走动,改变事物并尝试。 :) 帮自己一个忙,删除所有 jQuery 代码,特别是 Ajax 处理程序中的代码。如果您想要不同的 HTML,只需更新您的组件即可。
直接回答你的问题,并在检查 react-paginate
后文档,它只为您呈现一个分页器,但您仍然必须render
仅显示的项目数。在您的代码中,您正在映射完整的 this.state.items
数组,每次都会渲染每本书。
最重要的是,我看到您正在 onPerPage
中创建新的状态片段和onSelect
您未在 constructor
中初始化的方法.
您的应用程序需要的唯一状态是:
items
从 API 调用返回- 当前页面
- 可选:页面大小(每页的项目数),您可以将其声明为组件外部的常量,并在需要的任何地方重用它,如
const PAGE_SIZE = 9
。您稍后可以将其变成prop
因此您的组件的默认页面大小可以从外部进行配置。
给定前 2 个键,在 constructor
中声明您的初始状态像:
this.state = {
items: [],
currentPage: 1
}
然后,这是重要的部分,提取您的 items
至<Book />
将逻辑映射到函数,该函数考虑了 PAGE_SIZE
和currentPage
仅从数组中选择相关项目,例如:
renderBooks(){
var startIndex = (this.state.currentPage-1)*PAGE_SIZE
var endIndex = startIndex + PAGE_SIZE
return this.state.items.slice(startIndex, endIndex).map(item =>
<Book {...your_props} />
}
最后,在渲染方法中只需调用 renderBooks()
每当您想要渲染书籍时(即每次 this.state.items.length > 0
)都会运行该函数。
在 Paginate 组件的事件处理程序中,只需为 currentPage
设置适当的值即可。它会成功的。您不需要所有数学知识,只要分页器中没有下 0.25 页按钮,您就可以一直使用整数。 :)
希望对您有帮助!
PS:那是什么Bookshelf()
调用你的 AJAX 处理程序?你应该只setState({ items })
那里!!并考虑您的 render
中的新状态所有组件中的方法。
关于javascript - 使用 React 进行分页,解决 JSON 数据问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41875539/