Я пытаюсь извлечь данные из редукса в FlatList, а onRefresh = {} дает мне бесконечный цикл.Когда я не использую Redux, это работает, но когда я переместил процесс извлечения в Redux, я запутался.
Может кто-нибудь описать мне, что я делаю неправильно?
Заранее спасибо.
используй мою закуску: https://snack.expo.io/@thesvarta/redux-with-flatlist
Вот мой компонент
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
View,
Text,
FlatList,
StatusBar,
StyleSheet,
ActivityIndicator,
TouchableOpacity,
TouchableHighlight,
Image,
Button,
SearchBar,
TextInput,
} from 'react-native';
import TextDetails from '../TextDetails/TextDetails';
import {
fetchDataOptions,
resetDataOptions,
selectOptions,
} from '../store/actions/index';
class Search extends Component {
constructor(props) {
super(props);
this.state = {
page: 1,
loading: false,
refreshing: false,
};
}
componentDidMount() {
this.props.onResetDataOptions();
this.props.onFetchDataOptions(this.state.page, this.props.GroupBy);
console.log('component_data', this.props.fetch_data_options);
}
handleRefresh = () => {
this.props.onResetDataOptions(); // Resets fetch_data_options
this.setState(
{
page: 1,
refreshing: true,
},
() => {
this.props.onFetchDataOptions(this.state.page, this.props.GroupBy);
}
);
};
handleLoadMore = () => {
if (!this.props.fetch_data_error) {
this.setState(
{
page: this.state.page + 1,
},
() => {
this.props.onFetchDataOptions(this.state.page, this.props.GroupBy);
console.log('load_more', this.state.page);
}
);
} else {
this.setState(
{
page: 1,
},
() => {
this.props.onFetchDataOptions(this.state.page, this.props.GroupBy);
console.log('load_more_error', this.state.page);
}
);
}
};
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '100%',
backgroundColor: '#CED0CE',
}}
/>
);
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: '#CED0CE',
}}>
<ActivityIndicator animating size="large" />
</View>
);
};
renderRow = ({ item, index }) => {
return (
<View style={styles.ListContainer}>
<View style={styles.Text}>
<TextDetails Size={18}>{item.name}</TextDetails>
</View>
</View>
);
};
render() {
return (
<View style={styles.SearchContatiner}>
<View style={styles.Search}>
<View style={styles.ImageIcon}>
<Image
style={styles.Image}
resizeMode="contain"
source={require('../images/sokbla.png')}
/>
</View>
<View style={styles.InputBox}>
<TextInput
style={styles.InputText}
onChangeText={text => this.setState({ query: text })}
placeholder={'Search for ' + this.props.Title}
value={this.state.query}
/>
</View>
<TouchableOpacity
onPress={() => alert("remove query")}
style={styles.KryssIcon}>
<Image
style={styles.ImageKryss}
resizeMode="contain"
source={require('../images/kryssbla.png')}
/>
</TouchableOpacity>
</View>
<View style={styles.Lista}>
<FlatList
style={styles.Flatlist}
data={this.props.fetch_data_options}
renderItem={this.renderRow}
keyExtractor={item => item.name}
ItemSeparatorComponent={this.renderSeparator}
ListFooterComponent={this.renderFooter}
onRefresh={this.handleRefresh}
refreshing={this.state.refreshing}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={0}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
Lista: {
marginTop: 20,
},
Flatlist: {
width: '100%',
height: 300,
},
ListContainer: {
flexDirection: 'row',
width: '100%',
height: 40,
},
Text: {
marginLeft: '10%',
width: '70%',
justifyContent: 'center',
},
SearchContatiner: {},
Search: {
width: '100%',
height: 60,
backgroundColor: 'rgb(240,240,240)',
flexDirection: 'row',
},
Image: {
width: 23,
height: 33,
},
ImageIcon: {
justifyContent: 'center',
width: '15%',
alignItems: 'center',
},
InputBox: {
width: '70%',
justifyContent: 'center',
},
InputText: {
paddingLeft: 20,
width: '100%',
height: 50,
fontSize: 20,
},
KryssIcon: {
justifyContent: 'center',
width: '15%',
alignItems: 'center',
},
ImageKryss: {
width: 18,
height: 28,
},
});
const mapStateToProps = state => {
return {
fetch_data_options: state.filter.fetch_data_options,
fetch_data_error: state.filter.error,
status: state.filter.status,
};
};
const mapDispatchToProps = dispatch => {
return {
onFetchDataOptions: (page, group_by) =>
dispatch(fetchDataOptions(page, group_by)),
onResetDataOptions: () => dispatch(resetDataOptions()),
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(Search);
Вот мое действие
import {
FETCHING_DATA_OPTIONS,
FETCH_DATA_OPTIONS_SUCCESS,
FETCH_DATA_OPTIONS_FAILURE,
FETCH_DATA_OPTIONS_RESET,
} from './actionTypes';
export const fetchDataOptions = (page, group_by) => {
return dispatch => {
dispatch(getDataOptions());
return fetch(
'https://ollenorstrom.se/ollenorstrom.se/avoka/api/getOptions.php?page=' +
page +
'&row_per_page=5&group_by=' +
group_by
)
.then(res => res.json())
.then(json => {
//$json[0] containts .DATA, .STATUS, .MESSAGE
//.STATUS can be 200 or 404, if its 404 it means that .DATA is empty
if (json[0].STATUS == 200) {
return dispatch(
getDataOptionsSuccess(json[0]),
console.log('fetched_data', json[0])
);
} else {
return dispatch(getDataOptionsFailure());
}
})
.catch(err => dispatch(getDataOptionsFailure(err)));
};
};
export const resetDataOptions = () => {
return {
type: FETCH_DATA_OPTIONS_RESET
};
};
function getDataOptions() {
return {
type: FETCHING_DATA_OPTIONS,
};
}
function getDataOptionsSuccess(data) {
return {
type: FETCH_DATA_OPTIONS_SUCCESS,
data: data.DATA,
status: data.STATUS
};
}
function getDataOptionsFailure() {
return {
type: FETCH_DATA_OPTIONS_FAILURE,
};
}