Last active
January 22, 2019 09:42
-
-
Save EQuimper/4a3981d2e93fe44870732fa94a00e4bc to your computer and use it in GitHub Desktop.
reducer react-native
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import { | |
FETCH_FEED_IMAGES, | |
FETCH_FEED_IMAGES_ERROR, | |
FETCH_FEED_IMAGES_SUCCESS, | |
LIKED_PHOTO, | |
LIKED_PHOTO_ERROR, | |
LIKED_PHOTO_SUCCESS, | |
DISLIKED_PHOTO, | |
DISLIKED_PHOTO_ERROR, | |
DISLIKED_PHOTO_SUCCESS, | |
DELETED_PHOTO, | |
DELETED_PHOTO_ERROR, | |
DELETED_PHOTO_SUCCESS, | |
SELECT_PHOTO_FOR_DETAILS, | |
} from '../actions/feed'; | |
const INITIAL_STATE = { | |
isFetched: false, | |
data: [], | |
error: null, | |
selectPhotoId: '', | |
}; | |
export default (state = INITIAL_STATE, action) => { | |
switch (action.type) { | |
case FETCH_FEED_IMAGES: | |
return state; | |
case FETCH_FEED_IMAGES_SUCCESS: | |
return { | |
...state, | |
isFetched: true, | |
data: [...state.data, ...action.data], | |
}; | |
case FETCH_FEED_IMAGES_ERROR: | |
return { | |
...state, | |
isFetched: true, | |
error: action.e, | |
}; | |
case LIKED_PHOTO: | |
return { | |
...state, | |
data: state.data.map( | |
item => | |
(item._id === action.photoId | |
? { | |
...item, | |
liked: true, | |
likedCount: item.likedCount + 1, | |
} | |
: item), | |
), | |
}; | |
case LIKED_PHOTO_SUCCESS: | |
return state; | |
case LIKED_PHOTO_ERROR: | |
return { | |
...state, | |
error: action.e, | |
data: state.data.map( | |
item => | |
(item._id === action.photoId | |
? { | |
...item, | |
liked: false, | |
likedCount: item.likedCount - 1, | |
} | |
: item), | |
), | |
}; | |
case DISLIKED_PHOTO: | |
return { | |
...state, | |
data: state.data.map( | |
item => | |
(item._id === action.photoId | |
? { | |
...item, | |
liked: false, | |
likedCount: item.likedCount - 1, | |
} | |
: item), | |
), | |
}; | |
case DISLIKED_PHOTO_SUCCESS: | |
return state; | |
case DISLIKED_PHOTO_ERROR: | |
return { | |
...state, | |
error: action.e, | |
data: state.data.map( | |
item => | |
(item._id === action.photoId | |
? { | |
...item, | |
liked: true, | |
likedCount: item.likedCount + 1, | |
} | |
: item), | |
), | |
}; | |
case DELETED_PHOTO: | |
return { | |
...state, | |
data: state.data.filter(item => item._id !== action.photoId), | |
}; | |
case DELETED_PHOTO_SUCCESS: | |
return state; | |
case DELETED_PHOTO_ERROR: | |
return { | |
...state, | |
error: action.e, | |
data: state.data.filter(item => item._id !== action.photoId), | |
}; | |
case SELECT_PHOTO_FOR_DETAILS: | |
return { | |
...state, | |
selectPhotoId: action.id, | |
}; | |
default: | |
return state; | |
} | |
}; | |
// LIST | |
// @flow | |
import React, { Component } from 'react'; | |
import { | |
ListView, | |
RefreshControl, | |
FlatList, | |
View, | |
ActivityIndicator, | |
} from 'react-native'; | |
import PhotoCard from './PhotoCard'; | |
import Colors from '../utils/colors'; | |
export default class FeedList extends Component { | |
state = { | |
// dataSource: null, | |
loading: false, | |
offset: 0, | |
error: null, | |
refreshing: false, | |
}; | |
// componentWillMount() { | |
// const ds = new ListView.DataSource({ | |
// rowHasChanged: (r1, r2) => r1 !== r2, | |
// }); | |
// this.setState({ | |
// dataSource: ds.cloneWithRows(this.props.photos), | |
// }); | |
// } | |
// componentWillReceiveProps(nextProps: Object) { | |
// this.setState({ | |
// dataSource: this.state.dataSource.cloneWithRows(nextProps.photos), | |
// }); | |
// } | |
_fetchImages = () => { | |
this.setState( | |
{ | |
loading: true, | |
}, | |
async () => { | |
await this.props.fetchFeedImages(this.state.offset); | |
this.setState({ loading: false, refreshing: false }); | |
}, | |
); | |
}; | |
_onRefresh = () => { | |
this.setState( | |
{ | |
refreshing: true, | |
}, | |
() => { | |
this._fetchImages(); | |
}, | |
); | |
}; | |
_renderFooter = () => { | |
console.log('loading', this.props.loading); | |
if (!this.state.loading) return null; | |
return ( | |
<View style={{ paddingVertical: 20 }}> | |
<ActivityIndicator animating color={Colors.primary} size="large" /> | |
</View> | |
); | |
}; | |
_handleFetchMore = () => { | |
this.setState( | |
{ | |
offset: this.state.offset + 5, | |
}, | |
() => { | |
this._fetchImages(); | |
}, | |
); | |
}; | |
render() { | |
console.log('PROPS', this.props); | |
return ( | |
<FlatList | |
contentContainerStyle={{ | |
paddingTop: 10, | |
}} | |
data={this.props.photos} | |
renderItem={({ item }) => ( | |
<PhotoCard | |
{...item} | |
selectPhotoForDetails={this.props.selectPhotoForDetails} | |
likedPhoto={this.props.likedPhoto} | |
dislikedPhoto={this.props.dislikedPhoto} | |
deletedPhoto={this.props.deletedPhoto} | |
/> | |
)} | |
keyExtractor={item => item._id} | |
ListFooterComponent={this._renderFooter} | |
onEndReached={this._handleFetchMore} | |
onEndThreshold={500} | |
refreshControl={ | |
<RefreshControl | |
refreshing={this.state.refreshing} | |
onRefresh={this._onRefresh} | |
title="Pull to refresh" | |
tintColor={Colors.primary} | |
titleColor={Colors.primary} | |
/> | |
} | |
/> | |
); | |
} | |
} | |
// Actions | |
export const FETCH_FEED_IMAGES = 'FETCH_FEED_IMAGES'; | |
export const FETCH_FEED_IMAGES_SUCCESS = 'FETCH_FEED_IMAGES_SUCCESS'; | |
export const FETCH_FEED_IMAGES_ERROR = 'FETCH_FEED_IMAGES_ERROR'; | |
export function fetchFeedImages(offset: number) { | |
return async (dispatch: Function, getState: Function) => { | |
dispatch({ type: FETCH_FEED_IMAGES }); | |
const { token } = getState().user; | |
try { | |
const { data } = await Feed.fetchFeed(token, offset || 0); | |
return dispatch({ type: FETCH_FEED_IMAGES_SUCCESS, data }); | |
} catch (e) { | |
return dispatch({ type: FETCH_FEED_IMAGES_ERROR, e }); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment