Skip to content

Instantly share code, notes, and snippets.

@EQuimper
Last active January 22, 2019 09:42
Show Gist options
  • Save EQuimper/4a3981d2e93fe44870732fa94a00e4bc to your computer and use it in GitHub Desktop.
Save EQuimper/4a3981d2e93fe44870732fa94a00e4bc to your computer and use it in GitHub Desktop.
reducer react-native
// @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