关于Relay的麻烦之处
问题背景
由于QueryRender是直接将数据塞进Render()里的
  handleUpdate = (hasNextPage, xdata) =>{
    console.log(3);
    const data = this.state.data.concat(xdata);
    this.setState({
      data: data,
      loadingMore: false,
      hasNextPage: hasNextPage
      }, () => {
        window.dispatchEvent(new Event('resize'));
      });
  }
  render(){
    return(
      <QueryRenderer
      environment={env}
      query={SearchListQuery}
      variables={{
        search: this.props.search,
        first: this.props.pageSize,
        after: this.state.after
      }}
      render={({error, props}) => {
      if (error) {
          console.log(error)
      }
      if (!props) {
          return (<Spin   className={"selection-spin"} size={'large'}/>)
      }
      this.handleUpdate(props.bookList.hasNextPage, props.bookList.edges);
      const loadMore = this.state.hasNextPage ? (
        <div style={{ textAlign: 'center', marginTop: 12, height: 32, lineHeight: '32px' }}>
          {this.state.loadingMore && <Spin />}
          {!this.state.loadingMore && <Button onClick={() =>  {
            this.setState({
              loadingMore: true,
              after: props.bookList.pageInfo.endCursor});
          }}>加载更多</Button>}
        </div>
      ) : null;
      const mydata = this.state.data.concat(props.bookList.edges);
      return (
        <SearchListComponent  loadMore={loadMore}  dataSource={mydata}/>
      )
      }}
      />
    )
  }
直接在render里进行setState会导致组件无限循环渲染,当然把queryrender取缔掉用fetch替换可以解决,但是怎么在使用relay的同时直接setState呢?
改进一:
export default class SearchList extends PureComponent{
  state={
    after: "",
    data: [],
  }
  updateAfter = (after, xdata) =>{
    const data = this.state.data.concat(xdata);
    this.setState({after: after, data: data},
    () =>{
      window.dispatchEvent(new Event('resize'));
    });
  }
  render(){
    return(
      <QueryRenderer
      environment={env}
      query={SearchListQuery}
      variables={{
        search: this.props.search,
        first: this.props.pageSize,
        after: this.state.after
      }}
      render={({error, props}) => {
      if (error) {
          console.log(error)
      }
      return (
        <SearchListComponent
        loading={!props && this.state.after== ""}
        loadingMore={!props}
        updateAfter={() => this.updateAfter(props.bookList.pageInfo.endCursor, props.bookList.edges)}
        hasNextPage={props ? props.bookList.pageInfo.hasNextPage : null}
        dataSource={props ? this.state.data.concat(props.bookList.edges) : this.state.data}/>
      )
      }}
      />
    )
  }
}
class SearchListComponent extends PureComponent{
    constructor(props){
      super(props)
    }
    componentWillReceiveProps = (nextProps) =>{
      console.log(1)
      window.dispatchEvent(new Event('resize'));
    }
    render(){
      const loadMore = this.props.hasNextPage ? (
        <div style={{ textAlign: 'center', margin: 12, height: 32, lineHeight: '32px' }}>
          {this.props.loadingMore && <Spin />}
          {!this.props.loadingMore && <Button onClick={() =>{
            this.props.updateAfter();
          }}>加载更多</Button>}
        </div>
      ) : null;
      return(
        <List
        itemLayout="horizontal"
        loading={this.props.loading}
        loadMore={loadMore}
        dataSource={this.props.dataSource}
        grid={{ gutter: 24, xs: 1, sm: 1, md: 1, lg: 1, xl: 1, xxl: 1}}
        renderItem={item=> (
          <List.Item>
          <a href={`/info/${item.node.bookId}`}>
          <Card
          hoverable
          bordered={false}
          className={"book-list" }
          cover={<img alt={item.node.bookName} src={item.node.cover} />}>
            <Meta
              title={item.node.bookName}
              description={
                <div>
                  <div className="book-list-summary" >{item.node.summary.replace(/<br>/g, '        ')}</div>
                  <div className="book-list-info"><span>{item.node.author}</span><span className="split">|</span><span style={{color: 'red'}}>{item.node.clickTimes}</span> 点击</div>
                </div>
              }
            />
          </Card>
          </a>
        </List.Item>
        )}
        />
      )
    }
  }
缺陷:点击加载更多会闪一下,因为render会走两遍,第一遍是加载中,return null
关于Relay的麻烦之处的更多相关文章
- 【译】Unity3D Shader 新手教程(1/6)
		本文为翻译,附上原文链接. 转载请注明出处--polobymulberry-博客园. 刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D ... 
- 前馈网络求导概论(一)·Softmax篇
		Softmax是啥? Hopfield网络的能量观点 1982年的Hopfiled网络首次将统计物理学的能量观点引入到神经网络中, 将神经网络的全局最小值求解,近似认为是求解热力学系统的能量最低点(最 ... 
- Node.js + Web Socket 打造即时聊天程序嗨聊
		前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ... 
- 更好的pip工作流
		转自:http://codingpy.com/article/a-better-pip-workflow-recommended-by-kenneth/ 现在大家开发Python应用时,在代码库的根目 ... 
- [转]passport.js学习笔记
		概述 passport.js是Nodejs中的一个做登录验证的中间件,极其灵活和模块化,并且可与Express.Sails等Web框架无缝集成.Passport功能单一,即只能做登录验证,但非常强大, ... 
- C++中函数变量布局小结
		把布局作为一种信仰(Layout as Religion). ... 
- Git使用相关
		Git使用相关 使用git这么久还是时不时碰到小问题,根本原因在于没有仔细研究和做笔记 Git修改remote地址 之前一直使用的ssh的地址,估计是没配置好,每次都需要输密码烦死了,今天看到个用ht ... 
- [java] 汇率换算器实现(1)
		[java] 汇率换算器实现(1) // */ // ]]> [java] 汇率换算器实现(1) Table of Contents 1 问题描述 2 类设计 3 初步实现 3.1 建立项目 ... 
- 【译】使用UIKit进行面向对象的编程
		在WWDC 2015上,Apple谈了Swift中面向协议编程的话题,令人深思.在那之后,好像每个人都在讨论关于协议扩展的话题,这个新的语言特性使每个人都有所困惑. 我阅读了许多关于Swift中协议的 ... 
随机推荐
- leetcode720
			public class Solution { public string LongestWord(string[] words) { var maxlist = new List<string ... 
- ARP数据包伪造
			一台网络中的计算机,其传递到网络中的数据包的内容是完全由其软硬件逻辑决定的,软件可以操控硬件,硬件亦是一种特殊的软件,所以,接收者只根据数据包的内容,绝不可能判定此数据包的真正来源,一切都是可以伪 ... 
- 用django实现redirect的几种方法总结
			用django开发web应用, 经常会遇到从一个旧的url转向一个新的url.这种隐射也许有规则,也许没有.但都是为了实现业务的需要.总体说来,有如下几种方法实现 django的 redirect.1 ... 
- 转 CentOS下面安装RVM+ruby+Rails
			CentOS6.2下面安装RVM+ruby+Rails (1)RVM官方网站应该是改版过一次, 使用 curl -L https://get.rvm.io | bash -s stable 下载并安装 ... 
- maven如何引入servlet-api和jsp-api
			废话不多说,直接上代码 <dependency> <groupId>javax.servlet</groupId> <artifactId>javax. ... 
- solr的客户端操作:使用solrj进行curd操作
			导入相关的jar包 <dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-s ... 
- VUE+WebPack游戏设计:'乘法防线'游戏设计
- Spark internal - 多样化的运行模式(上)
			Spark的运行模式多种多样,在单机上既可以以本地模式运行,也可以以伪分布式模式运行.而当以分布式的方式运行在Cluster集群中时,底层的资源调度可以使用Mesos 或者是Hadoop Yarn , ... 
- 优化mysql slave的同步速度
			测试环境:Red Hat Enterprise Linux Server release 6.3 (Santiago)Server version: 5.6.22-log MySQL Communit ... 
- 监控磁盘IO
			一.添加userparameter_io.conf配置文件 在/etc/zabbix/zabbix_agentd.d下添加userparameter_io.conf, 文件内容如下: UserPara ... 
