Javascript 使用react infinite scroller创建待办事项列表

Javascript 使用react infinite scroller创建待办事项列表,javascript,reactjs,infinite-scroll,Javascript,Reactjs,Infinite Scroll,尝试使用react infinite scroller创建待办事项列表。列表将显示20个TODO,滚动时将显示下一个TODO。我从“”获取TODO。获取的TODO保存在TODO变量中 我对这个示例进行了建模: 此处演示: 我看不到加载..出现并获取更多任务 代码如下: 如何将页面设置为从1更改为2,然后从2更改为3 class App extends Component { constructor (props) { super(props); this.state = {

尝试使用
react infinite scroller
创建待办事项列表。列表将显示20个TODO,滚动时将显示下一个TODO。我从“”获取TODO。获取的TODO保存在
TODO
变量中

我对这个示例进行了建模:

此处演示:

我看不到
加载..
出现并获取更多任务

代码如下:

如何将页面设置为从1更改为2,然后从2更改为3

class App extends Component {

  constructor (props) {
    super(props);
    this.state = {
      todos: [],
      hasMoreTodos: true,
      page: 1
    }
  }

  loadTodos(page){
    var self = this;

    const url = `/api/v1/project/tasks?expand=todos&filter%5Btype%5D=400&${page}&${per_page}`;

    /*if(this.state.nextHref) {
      url = this.state.nextHref;
    }*/

    axios.get(url, {
      'page': 1,
      'per-page': 10
    })
    .then(resp => {
      if(resp) {
        var todos = [self.state.todos, ...resp];

        /*if(resp.next_href) {
          self.setState({
            todos: todos,
            nextHref: resp.next_href
          });*/
        } else {
          self.setState({
              hasMoreTodos: false
          });
        }
      }
    });
  }


  render () {
    const loader = <div className="loader">Loading ...</div>;

    var divStyle = {
       'width': '100px';
       'height': '300px';
       'border': '1px solid black',
       'scroll': 'auto'
    };

    const items = this.state.todos.map((todo, i) => 
        <div className="track" key={todo.id}>
            <p className="title">{todo.title}</p>
        </div>);


    return (
        <div style={divStyle}>
            <InfiniteScroll
                pageStart={1}
                loadMore={this.loadTodos.bind(this)}
                hasMore={this.state.hasMoreTodos}
                loader={loader}>
            <div className="tracks">
                {items}
            </div>
            </InfiniteScroll>
        </div>
    )
  }
}
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
待办事项:[],
哈斯莫雷托多斯:是的,
页码:1
}
}
加载待办事项(第页){
var self=这个;
const url=`/api/v1/project/tasks?expand=todos&filter%5Btype%5D=400&${page}&${per_page}`;
/*if(this.state.nextHref){
url=this.state.nextHref;
}*/
获取(url{
“页面”:1,
“每页”:10
})
。然后(resp=>{
如果(resp){
var todos=[self.state.todos,…resp];
/*如果(分别下一个){
自我状态({
待办事项:待办事项,
nextHref:resp.next_href
});*/
}否则{
自我状态({
哈斯莫雷托多斯:错
});
}
}
});
}
渲染(){
常量加载器=加载。。。;
变量divStyle={
“宽度”:“100px”;
‘高度’:‘300px’;
“边框”:“1px纯黑”,
“滚动”:“自动”
};
const items=this.state.todos.map((todo,i)=>

{todo.title}

); 返回( {items} ) } }
更新2

代码如下:

从“react infinite scroller”导入InfiniteScroll;
从“axios”导入axios;
类应用程序扩展组件{
构造函数(){
超级();
此.state={
待办事项:[],
哈斯莫雷托多斯:是的,
页码:1,
下页:1,
完成加载:false
};
}
loadTodos=(id)=>{
如果(!this.state.finishedLoading){
常量参数={
id:'1234',
第页:this.state.nextPage,
“每页”:10,
}
axios({
url:`/api/v1/project/tasks`,
方法:“获取”,
params
})
.然后(res=>{
让{todos,nextPage}=this.state;
如果(resp){//resp或resp.data????
这是我的国家({
todos:[…todos,…resp],//resp或resp.data????
下一页:下一页+1,
完成加载:响应长度>0//响应或响应数据????
});
}
})
.catch(错误=>{
console.log(错误);
}) 
}
}
render(){
常量加载器=加载。。。;
常量divStyle={
“高度”:“300px”,
“溢出”:“自动”,
“宽度”:“200px”,
“边框”:“1px纯黑”
}
const items=this.state.todos.map((todo,i)=>

{todo.title}

); 返回( this.scrollParentRef=ref}> this.scrollParentRef} > {items} ); } }
编辑:我刚刚意识到你是一个起点:

为什么你一下子就得到了一切 因为您的源代码只是一个大的JSON

您使用的脚本中的逻辑适用于SoundCloud的API,该API对庞大的列表进行分页(也称为逐块返回)

您的API不分页,因此您可以同时接收所有内容

请参见SoundCloud API的示例结果:

{
    "collection": [
        {
            "kind": "track",
            "id": 613085994,
            "created_at": "2019/04/29 13:25:27 +0000",
            "user_id": 316489116,
            "duration": 476281,
            [...]
        },
        [...]
    ],
    "next_href": "https://api.soundcloud.com/users/8665091/favorites?client_id=caf73ef1e709f839664ab82bef40fa96&cursor=1550315585694796&linked_partitioning=1&page_size=10"
}
next_href
中的URL给出了下一批项目的URL(URL相同,但每次“cursor”参数都不同)。这就是无限列表工作的原因:每次都会得到下一批

必须实现服务器端分页才能实现此结果。

回应您的编辑:

更新了我的问题

如何设置代码中注释的这些位置

/*if(this.state.nextHref) {
    url = this.state.nextHref; }*/

/*if(resp.next_href) {   self.setState({
    todos: todos,
    nextHref: resp.next_href   });*/
忘了加载nextHref吧,你没有。您拥有的是当前页码(直到您加载内容的页面)

尝试以下几点:

if (!self.state.finishedLoading) {
  qwest.get("https://your-api.org/json", {
    page: self.state.nextPage,
    'per-page': 10,
  }, {
    cache: true
  })
  .then((xhr, resp) => {
    let {todos, nextPage} = self.state;

    if(resp) {
      self.setState({
        todos: [...todos, ...resp],
        nextPage: nextPage + 1,
        finishedLoading: resp.length > 0, // stop loading when you don't get any more results
      });
    }
  });
}
一些挑剔 除了使用具有副作用的
Array.map
(仅针对该副作用)之外,您正在变异
self.state

你可以这样写:

    var todos = [self.state.todos, ...resp];
此处地图的用法相同:

var items = [];
this.state.todos.map((todo, i) => {
    items.push(
        <div className="track" key={todo.id}>
          <p className="title">{todo.title}</p>
        </div>
    );
});
var项目=[];
this.state.todos.map((todo,i)=>{
推(

{todo.title}

); });
应写明:

const items = this.state.todos.map((todo, i) => 
    <div className="track" key={todo.id}>
      <p className="title">{todo.title}</p>
    </div>);
const items=this.state.todos.map((todo,i)=>

{todo.title}

);
给定
缓存:true
-测试前是否清除/禁用缓存?@Aprillion,在那里我可以清除/禁用缓存。在“网络中的开发工具”选项卡中,我选中了“禁用缓存”复选框,但它对我不起作用,但一次加载200项。但有一件事(不相关?)是:你使用的技术是错误的。如果您对回调产生的副作用感兴趣,而不是对其返回值感兴趣,请使用。hugo it不适合我。元素立即被下载。滚动时,应向其充电。应该显示10个元素,它们都是allI不是指浏览器缓存,而是由
qwest
实现的功能,该功能由
cache:true
配置设置-我不知道该功能如何工作,但可能将其更改为
cache:false
用于测试可能会有所帮助。。。如果非常详细的答案不能解决问题,在我真正的api中,我有分页:例如:
page=2&per page=20
。我能用它吗?链接分区===页面?页面大小===每页?什么是“下一步”?我只有一页,每页你能吗
    var todos = self.state.todos;
    resp.map((todo) => {
      todos.push(todo);
    });
    var todos = [self.state.todos, ...resp];
var items = [];
this.state.todos.map((todo, i) => {
    items.push(
        <div className="track" key={todo.id}>
          <p className="title">{todo.title}</p>
        </div>
    );
});
const items = this.state.todos.map((todo, i) => 
    <div className="track" key={todo.id}>
      <p className="title">{todo.title}</p>
    </div>);