React&Redux中Scroll List封装实践

前端之家收集整理的这篇文章主要介绍了React&Redux中Scroll List封装实践前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
一直直在写一个前端项目,来分享一些Scroll封装的实践

本宝宝看着你们只收藏不点赞都有小情绪!!!!哼

设计目标

因为项目中需要大量的类似Scroll List,ListView页面

github上看了圈感觉没有特别喜欢的,就自己来封装了一下
层次结构如下:

|-Scroll//主要处理诸如下拉刷新,上拉加载,加载状态,错误信息等
|-----List //主要是List主体 
|--------ListEl //返回List里单个Component,

使用方式

可以像这样简洁的使用这个封装的Scroll List(or List View)
有种来到了开发Windows RT、WPF使用ListView template的即视感

<Scroll
        firstLoading={foo.FirstLoading}
        fistLoading={foo.ListLoading}
        isEnd={foo.isEnd}
        isFetch={foo.isFetch}
        fetchFailed={foo.fetchFailed}
        FailedMag={foo.FailedMag}
    >
        <List
            entities={coursecate.entities}
            result={coursecate.result}
            type={'samllCourseCate'}
        >
        </List>
    </Scroll>

开始封装

说明:JSON格式扁平化(normalizr)

我在项目中使用normalizer来格式扁平化JSON数据

开发复杂的应用时,不可避免会有一些数据相互引用。建议你尽可能地把 state 范式化,不存在嵌套。把所有数据放到一个对象里,每个数据以 ID 为主键,不同数据相互引用时通过 ID 来查找。把 应用的 state 想像成数据库 。这种方法在 normalizr 文档里有详细阐述。
normalizr:将嵌套的JSON格式扁平化,方便被Redux利用;

举个例子

[{
  id: 1,title: 'Some Article',author: {
    id: 1,name: 'Dan'
  }
},{
  id: 2,title: 'Other Article',name: 'Dan'
  }
}]

处理后会变成

{
  result: [1,2],entities: {
    articles: {
      1: {
        id: 1,author: 1
      },2: {
        id: 2,author: 1
      }
    },users: {
      1: {
        id: 1,name: 'Dan'
      }
    }
  }
}

CommonScorll.js

import React,{ PropTypes,Component } from 'react';

class CommonScorll extends Component {
    constructor(props) {
        super(props);
        const {FirstLoading,ListLoading} =this.props;
        this.ListScroll=this.ListScroll.bind(this);
        this.FirstLoading=()=>FirstLoading();
        this.ListLoading=()=>ListLoading();
    }
    componentDidMount() {
        console.log('common scroll componentDidMount')       
        //下拉刷新监听绑定
        window.addEventListener('scroll',this.ListScroll);
        //初次Load
        this.FirstLoading;
    }
    componentWillUnmount(){
        //移除监听
        window.removeEventListener('scroll',this.ListScroll);
    }
    ListScroll(e) {
        var scrollTop = document.body.scrollTop; 
        var offsetHeight = document.body.offsetHeight; 
        var scrollHeight = document.body.scrollHeight; 
        if (scrollTop >= scrollHeight - offsetHeight) { 
             this.ListLoading;
        } 
    }
    render(){
        console.log('common scroll render')
        const {
            isFetch,isEnd,fetchFailed,FailedMsg,EmptyElement
                }=this.props;
        let NoMore=();
        if(isEnd){
            NoMore=(
                ...
            );
        }
        ...//根据你的需求处理 底部如:加载更多,加载失败时重新加载等
        
        return(
            <div >
               {this.props.children}//因为List主体是被包裹在Scroll中的,所以加载children
               ...    
            </div>
        );
    }

}

export default CommonScorll;

CommonList.js

import React,Component } from 'react';
import {ListEl} from './ListEl'

class CommonList extends Component {
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        console.log('common list componentDidMount')       
    }
    render(){
            console.log('common list render')
            const {
                    entities,result,type
                    }=this.props;
                    //数据经过normalize格式化
            let datas=[<div key=0/>];
            if(result.length!==0){
                datas=[];
                result.forEach(function(id) {
                    datas.push(ListEl(id,entities,type))//ListEl是一个function 
                })
            }
            return(
                <div>
                    {datas}
                </div>
            );
        }
}

export default CommonList;

ListEl.js

import React,Component } from 'react';
import SmallCourseCate from '../Common/CourseCate/SmallCourseCate'

export function ListEl(id,entites,type) {
    switch (type) {
        case 'samllCourseCate':
            if(entites.coursecates[id]){
                let coursecate=entites.coursecates[id];
                return(
                    <SmallCourseCate
                        key={id}
                        coursecate={coursecate}
                    />
                )
            }else{
                return (
                    <div>
                    <p>small coursecate el try get coursecate is null</p>
                    </div>
                )
            }
        ...
        default:
        return (
            <div>
                <p>el type undefind</p>
            </div>
        )
    }
}

总结&TODO

  1. 封装后总体Scroll List比较优雅和快捷

  2. 但是欠缺性能优化,使用immutable、shouldComponentUpdate优化性能

猜你在找的React相关文章