React Native FlatList 获得无限循环 onRefresh [英] React Native FlatList gets infinity loop onRefresh
问题描述
我试图从 redux 获取数据到 FlatList 并且 onRefresh={} 给了我一个无限循环.当我不使用 redux 时它可以工作,但是当我将我的提取移动到 redux 操作时,我感到困惑.
Im trying to fetch data from redux to a FlatList and onRefresh={} gives me an infinity loop. When i dont use redux it works but when i moved my fetching into a redux action im getting confused.
有人可以向我描述我做错了什么吗?
Can someone describe to me what I am doing wrong?
提前致谢.
使用我的零食: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,
};
}
推荐答案
您在调度 API 调用后没有更改 refreshing
状态变量的值.它在您的 handleRefresh
函数中设置为 true
,但永远不会设置回 false
.
You haven't changed the value of refreshing
state variable after dispatching the API call. It's set as true
in your handleRefresh
function but never set back to false
.
使用生命周期方法 componentWIllUpdate
或 componentDidUpdate
之一来检查 props 是否发生变化(API 调用成功或失败),并更改你的 的状态将
变量刷新为false.
Use one of the lifecycle methods componentWIllUpdate
or componentDidUpdate
to check whether the props have changed (API call success or fail), and change the state of your refreshing
variable to false.
例如.在您的搜索组件中添加这个,
For eg. in your Search component add this,
componentDidUpdate(prevProps) {
//Check whether props have changed and isFetching is false
if (this.props.isFetching !== prevProps.isFetching && !this.props.isFetching) {
this.setState({refreshing:false});
}
}
还要检查 onEndReachedThreshold
的值是否为 0.用法说明 这里
Also check the value of onEndReachedThreshold
is 0. Usage is explained here
这篇关于React Native FlatList 获得无限循环 onRefresh的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!