一直直在寫一個前端項目,來分享一些Scroll封裝的實踐
由於項目中須要大量的相似Scroll List,ListView頁面:前端
github上看了圈感受沒有特別喜歡的,就本身來封裝了一下
層次結構以下:react
|-Scroll//主要處理諸以下拉刷新,上拉加載,加載狀態,錯誤信息等 |-----List //主要是List主體 |--------ListEl //返回List裏單個Component,
能夠像這樣簡潔的使用這個封裝的Scroll List(or List View)
有種來到了開發Windows RT、WPF使用ListView template的即視感git
<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>
我在項目中使用normalizer來格式扁平化JSON數據github
開發複雜的應用時,不可避免會有一些數據相互引用。建議你儘量地把 state 範式化,不存在嵌套。把全部數據放到一個對象裏,每一個數據以 ID 爲主鍵,不一樣數據相互引用時經過 ID 來查找。把 應用的 state 想像成數據庫 。這種方法在 normalizr 文檔裏有詳細闡述。
normalizr:將嵌套的JSON格式扁平化,方便被Redux利用;
舉個例子
[{ id: 1, title: 'Some Article', author: { id: 1, name: 'Dan' } }, { id: 2, title: 'Other Article', author: { id: 1, name: 'Dan' } }]
處理後會變成數據庫
{ result: [1, 2], entities: { articles: { 1: { id: 1, title: 'Some Article', author: 1 }, 2: { id: 2, title: 'Other Article', author: 1 } }, users: { 1: { id: 1, name: 'Dan' } } } }
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;
import React, { PropTypes, 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;
import React, { PropTypes, 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> ) } }