问题背景

由于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>&nbsp;点击</div>
</div>
}
/>
</Card>
</a>
</List.Item>
)}
/>
)
}
}

缺陷:点击加载更多会闪一下,因为render会走两遍,第一遍是加载中,return null

关于Relay的麻烦之处的更多相关文章

  1. 【译】Unity3D Shader 新手教程(1/6)

    本文为翻译,附上原文链接. 转载请注明出处--polobymulberry-博客园. 刚开始接触Unity3D Shader编程时,你会发现有关shader的文档相当散,这也造成初学者对Unity3D ...

  2. 前馈网络求导概论(一)·Softmax篇

    Softmax是啥? Hopfield网络的能量观点 1982年的Hopfiled网络首次将统计物理学的能量观点引入到神经网络中, 将神经网络的全局最小值求解,近似认为是求解热力学系统的能量最低点(最 ...

  3. Node.js + Web Socket 打造即时聊天程序嗨聊

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前 ...

  4. 更好的pip工作流

    转自:http://codingpy.com/article/a-better-pip-workflow-recommended-by-kenneth/ 现在大家开发Python应用时,在代码库的根目 ...

  5. [转]passport.js学习笔记

    概述 passport.js是Nodejs中的一个做登录验证的中间件,极其灵活和模块化,并且可与Express.Sails等Web框架无缝集成.Passport功能单一,即只能做登录验证,但非常强大, ...

  6. C++中函数变量布局小结

    把布局作为一种信仰(Layout as Religion).                                                                       ...

  7. Git使用相关

    Git使用相关 使用git这么久还是时不时碰到小问题,根本原因在于没有仔细研究和做笔记 Git修改remote地址 之前一直使用的ssh的地址,估计是没配置好,每次都需要输密码烦死了,今天看到个用ht ...

  8. [java] 汇率换算器实现(1)

    [java] 汇率换算器实现(1) // */ // ]]>   [java] 汇率换算器实现(1) Table of Contents 1 问题描述 2 类设计 3 初步实现 3.1 建立项目 ...

  9. 【译】使用UIKit进行面向对象的编程

    在WWDC 2015上,Apple谈了Swift中面向协议编程的话题,令人深思.在那之后,好像每个人都在讨论关于协议扩展的话题,这个新的语言特性使每个人都有所困惑. 我阅读了许多关于Swift中协议的 ...

随机推荐

  1. c++ 字符检测 TCharacter

    c++ 字符检测 IsSurrogatePair,IsHighSurrogate,IsLowSurrogate,ConvertToUtf32http://docwiki.embarcadero.com ...

  2. 页面生成柱状图 --- D3.js

    转载自:https://www.cnblogs.com/fastmover/p/7779660.html D3.js从入门到"放弃"指南 前言 近期略有点诸事不顺,趁略有闲余之时, ...

  3. Balls(poj 3783)

    The classic Two Glass Balls brain-teaser is often posed as: “Given two identical glass spheres, you ...

  4. 手游为什么要热更新,C#为什么不能热更新,LUA为什么可以

    热更新是什么?简单的说就是打补丁,只补需要部分,不用重个游戏包重打上传 热更新问题的本质是代码更新而不是资源更新,为什么呢? 大型手游都是将补丁资源放在专门的WEB服务器上,游戏启动时动态下载并放入到 ...

  5. JS中如何获取当前时间及让时间格式化

    JS中获取当前时间和JAVA里获取当前时间一样,都是直接new Date即可.不同的是,JS中用var date=new Date();JAVA中用Data data=new Date();注:JS中 ...

  6. java 蓝桥杯算法提高 _2最大最小公倍数

    解题思路: 1. n是奇数,那就最大的三个数相乘2. n是偶数,得分两种情况了, ①如果n不是3的倍数,那就s=n*(n-1)*(n-3)---n与n-2同为偶数,故排除一个n-2: ②n是3的倍数, ...

  7. 基于HttpRunner的接口自动化测试平台HttpRunnerManager(二)

    https://github.com/HttpRunner/HttpRunnerManager HttpRunnerManager Design Philosophy 基于HttpRunner的接口自 ...

  8. ubuntu eclipse opencv环境配置

    项目——Properties——C/C++ Build——Settings 配置包含目录: GCC C++ Compiler   ——Includes /usr/include /usr/local/ ...

  9. mybaties 一对多关系映射

    背景: 数据库格式如下图所示 现在要统计出在一段时间内dimension_type为op即所有运营商的pv.uv.vv等指标的数组,以便页面显示出每个运营商在该事件段内历史指标曲线图. 分析: 返回的 ...

  10. 线上应用故障排查:高CPU占用

    转自:hankchen,http://www.blogjava.net/hankchen 一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. 以我们最近出现的一个实际故障 ...