美文网首页程序员笔记YAOPAI 团队博客React
探讨 React 生命周期何时渲染数据最友好

探讨 React 生命周期何时渲染数据最友好

作者: Yi罐可乐 | 来源:发表于2016-07-01 13:20 被阅读894次

    根据业务需求,要做一个用户收藏作品列表页,如图

    作品列表页

    如果用户没有收藏作品时,提示用户:

    没有收藏作品

    项目是基于 Reflux 的,直接上代码:

    class UserCollectList extends React.Component{
      constructor(props) {
        super(props);
        this.state = {
          works: [],
        }
      }
    
      componentWillMount() {
        // 这里向服务器请求数据(数据是一组数组)
         Actions.xxxx()
      }
    
      onSearchSuccess(data) {
        // Oh!从 store �里拿到数据了,存在 state 里
        this.setState({works: data})
      }
    
      render() {
        let CollectRow = <div></div>
        判断一下用户关注的有数据没
        if (!this.state.works.length) { 
          CollectRow = <div>你还没有收藏过作品:)</div>
        } else {
          CollectRow = this.state.works.map((data, i) => <div key={i}>{data}</div>)
        }
    
        return <div>{CollectRow}</div>
      }
    }
    
    // 一旦 Store 的数据发生变化,onSearchSuccess 就能随时接受数据
    ReactMixin.onClass(UserCollectList, Reflux.listenTo(Store, 'onSearchSuccess'));
    

    是不是看起来没什么问题?
    实际测试时,当用户有数据时,每次进入这个页面,(CollectRow)会先呈现:


    `CollectRow = <div>你还没有收藏过作品:)</div>`

    然后立刻(CollectRow)页面又恢复成了:

    `<div key={i}>{data}</div>`

    ** 问题出在 if (!this.state.works.length)上,因为页面刚加载时 this.state.works.length确实是 false,等服务器数据传递过来 又变成 true 了。 **

    ** 解决办法: **

    class UserCollectList extends React.Component{
      constructor(props) {
        super(props);
        this.state = {
          CollectRow: <div></div>,
        }
      }
    
      componentWillMount() {
        // 这里向服务器请求数据(数据是一组数组)
         Actions.xxxx()
      }
    
      onSearchSuccess(data) {
        // Oh!从 store �里拿到数据了,存在 state 里并使用
        if (data.length) { 
          this.setState({
            CollectRow:  <div>你还没有收藏过作品:)</div>
          })
        } else {
          this.setState({
            CollectRow : data.map((dataRow, i) => <div key={i}>{dataRow}</div>)
          })
        }
    
      render() {
        return <div>{this.state.CollectRow}</div>
      }
    }
    
    ReactMixin.onClass(UserCollectList, Reflux.listenTo(Store, 'onSearchSuccess'));
    

    ** 在 onSearchSuccess() 方法(连接 storecomponent 的「桥梁」 )里,数据通过 map() 处理后直接放入 state 里。**

    测试了下,页面不会出现上述的问题了:)
    当然,如果数据过多时,最好加一个 loading 小动画。

    如果疑问,欢迎评论提问~
    如有更好的方法,请赐教~

    开源项目 https://github.com/2remote/yaopai-mobile
    欢迎给我们提 issue 或 pull request。

    相关文章

      网友评论

      • darrell:你好,如果是使用redux遇到这个问题怎么办?
        Yi罐可乐: @Darrell 打开这个页面的时候,显示 loading,然后发起action,等待回调结果。有数据的话就显示数据,没有数据就提示没有数据。

      本文标题:探讨 React 生命周期何时渲染数据最友好

      本文链接:https://www.haomeiwen.com/subject/bfutjttx.html