关于Relay的麻烦之处
- 2019 年 10 月 5 日
- 筆記
问题背景
由于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