最後一天了 不能夠用待補帶過 硬是要把功能完成寫出來
今天我們要寫的就是 Lazy Scroll Loading 的功能
首先 我們要先安裝一個套件 redux-lazy-scroll
安裝部分就不說了 自己google就會知道
直接來看要怎麼使用吧
// lazy scroll
import ReduxLazyScroll from 'redux-lazy-scroll';
return(
<div className='posts-lazy-scroll'>
<ReduxLazyScroll
isFetching={this.props.isFetching}
errorMessage={this.props.errorMessage}
loadMore={this.loadPost}
hasMore={this.props.hasMore}>
// ... Something you wanna render
</ReduxLazyScroll>
<div className="row posts-lazy-scroll__messages">
{
this.props.isFetching &&
<Segment style={{width: '100%', padding: '20px 0 20px 0'}}>
<Dimmer active>
<Loader />
</Dimmer>
</Segment>
}
{
!this.props.hasMore && !this.props.errorMessage &&
<div className="alert-success">
<Icon size='large' name='check circle' style={{color:'green'}}> </Icon>
</div>
}
{
this.props.errorMessage &&
<div className="alert alert-danger">
{
this.props.errorMessage
}
</div>
}
</div>
</div>
ReduxLazyScroll 裡面的參數除了 loadMore 其他都是在 redux/model.js 設定預設值
export const SubjListData = Immutable.fromJS({
'InProcessList': [],
'FinishLazyLoad': {
isFetching: false,
FinishedList: [],
errorMessage: '',
skip: 0,
limit: 20,
hasMore: true
}
});
limit 就是我們設定給後端 一次要撈幾筆資料的設定值
loadPost(){
console.log("in loadPost Function");
this.props.onGetFinished(this.props.CompID, this.props.discid, this.props.UserID,
this.props.skip, this.props.limit, this.props.Token);
}
在component 裡面 我們會loadmore 去呼叫 loadPost 然後再去呼叫 container的onGetFinished(...)
container ~
// loading Library
import { connect } from 'react-redux';
// loading Component
import FinishedPage_CP from '../../../components/SubjListPage/FinishedPage';
// loading Action
import {
GetUserFinished
} from '../../../redux/actions/SubjListActions';
export default connect(
(state) => ({
IsLogin: state.getIn(['InitReducer', 'IsLogin']),
CompID: state.getIn(['InitReducer', 'CurrentUser', 'CompID']),
UserID: state.getIn(['InitReducer', 'CurrentUser', 'UserID']),
Token: state.getIn(['InitReducer', 'Token']),
isFetching: state.getIn(['SubjListReducers', 'FinishLazyLoad', 'isFetching']),
FinishedList: state.getIn(['SubjListReducers', 'FinishLazyLoad',
'FinishedList']),
errorMessage: state.getIn(['SubjListReducers', 'FinishLazyLoad',
'errorMessage']),
skip: state.getIn(['SubjListReducers', 'FinishLazyLoad', 'skip']),
limit: state.getIn(['SubjListReducers', 'FinishLazyLoad', 'limit']),
hasMore: state.getIn(['SubjListReducers', 'FinishLazyLoad', 'hasMore']),
}),
(dispatch) => ({
onGetFinished: (_compid, _discid, _userid, _skip, _limit, _token) => {
dispatch(GetUserFinished(_compid, _discid, _userid, _skip, _limit, _token))
}
}),
)(FinishedPage_CP);
接下來重頭戲 我們來看 Action 拿取結果後 如何到reducer裡面
Insert_Finished_List: (state, {payload}) => {
const _newFinishedList = List(payload.FinishedList);
const _mergeFinishedList = state.getIn(['FinishLazyLoad',
'FinishedList']).concat(_newFinishedList);
return state.setIn(['FinishLazyLoad', 'FinishedList'],
_mergeFinishedList.map((_item, _index) => {
let _mapItem = Map(_item);
return _mapItem.map((_subItem, _subIndex) => {
// || _subIndex === 'fav_data' || _subIndex === 'color_data'
if(_subIndex === 'is_ins_data')
{
return Map(_subItem);
}
return _subItem;
});
return Map(_item);
})
);
}
重點在於 如果你拉回來的陣列裡面包住物件裡面還有物件的話
一定要記得 Map(...) 做類似轉型的動作
否則你在頁面上做 XXX.getIn or XXX.get 都會失效喔~