­

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

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