一直直在写一个前端项目,来分享一些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> ) } }