我认为我的问题与redux有关。行为是当我到达loadmore项目(onEndReached)的底部时,滚动将回到顶部,而不是保持位置并添加item.It添加项目,但就像我说的,我回到顶部。预期的行为将是onEndReach必须保持位置而不是重新加载所有项目。我在此存储库中有以下简单代码:https://github.com/francoro/flatlistRedux 我将把代码也放在这里:
PostsList.js
import React, { Component } from 'react';
import { View, Image, FlatList, ListView, Text } from 'react-native';
import { connect } from 'react-redux';
import { fetchData } from './actions';
import { emptyData } from './actions';
class Login extends Component {
constructor() {
super();
this.position = 0;
}
componentWillMount() {
this.props.emptyData();
this.props.fetchData(this.props.tabId, 0, this.props.dateFilter, this.position);
}
/* componentWillReceiveProps(newProps) {
if (newProps.dateFilter !== this.props.dateFilter || newProps.tabId !== this.props.tabId) {
this.position = 0;
this.props.emptyData();
this.props.fetchData(newProps.tabId, 0, newProps.dateFilter, this.position);
}
} */
handleLoadMore = () => {
this.position += 10;
if (this.props.posts.data.total === this.props.posts.data.posts.length) {
console.log("ALL LOADED")
return
}
console.log("POSITION", this.position)
this.props.fetchData(this.props.tabId, 0, this.props.dateFilter, this.position);
};
renderRow({ item }) {
return (
<View>
<Text>{item._id}</Text>
<Image style={{ width: 200, height: 400 }} source={{ uri: item.image }} />
<Text>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam</Text>
</View>
);
}
render() {
return (
<View>
<FlatList
data={this.props.posts.data.posts}
renderItem={this.renderRow}
onEndReached={this.handleLoadMore}
keyExtractor={item => item._id}
onEndReachedThreshold={0.5}
/>
</View>
)
}
}
const mapStateToProps = state => {
return {
posts: state.dataReducer,
tabId: state.tabId,
dateFilter: state.dateFilter
}
}
const mapDispatchToProps = dispatch => {
return {
fetchData: (type, filter, dateFilter, position) => dispatch(fetchData(type, filter, dateFilter, position)),
emptyData: () => dispatch(emptyData())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Login)
我的App.js
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
import { Provider } from 'react-redux';
import configureStore from './src/configureStore';
import PostsList from './src/PostsList.js';
let store = configureStore();
export default class App extends Component<Props> {
render() {
return (
<Provider store={store}>
<View>
<PostsList />
</View>
</Provider>
);
}
}
configureStore.js
import {createStore, applyMiddleware} from 'redux';
import reducers from './reducers';
import thunk from "redux-thunk";
export default configureStore = () => {
let store = createStore(reducers, applyMiddleware(thunk));
return store;
}
actions / index.js
import { FETCHING_DATA, FETCHING_DATA_SUCCESS, FETCHING_DATA_FAILURE } from "../constants"
import getDataApi from '../api';
export const getData = () => {
return {
type: FETCHING_DATA
}
}
export const getDataSuccess = (newData, initialData = null) => {
return {
type: FETCHING_DATA_SUCCESS,
newData,
initialData
}
}
export const getDataFailure = () => {
return {
type: FETCHING_DATA_FAILURE
}
}
export const emptyDataStore = () => {
return {
type: 'EMPTY_DATA'
}
}
export const fetchData = (type, filter, dateFilter, position) => {
return (dispatch, getState) => {
const state = getState();
dispatch(getData())
getDataApi(type, filter, dateFilter, position)
.then(res => {
console.log("RES", res)
if (res !== false) {
console.log("entro")
if (state.dataReducer.data.length === 0) {
dispatch(getDataSuccess(res[1]))
} else {
dispatch(getDataSuccess(res[1], state.dataReducer.data))
}
}
})
.catch((err) => console.log(9999, err))
}
}
export const emptyData = () => {
return (dispatch) => {
dispatch(emptyDataStore())
}
}
api / index.js
const URL = "https://still-gorge-30183.herokuapp.com";
let fetching = false;
export default (type, filter, dateFilter, position) => {
if (fetching) return Promise.reject(new Error('Request in progress'));
console.log("URLl", `/search/${type}/${filter}/${dateFilter}/${position}/0/0`)
fetching = true;
return fetch(URL + `/search/${type}/${filter}/${dateFilter}/${position}/0/0`)
.then(response => Promise.all([response, response.json()]))
.then(([response, responseObj]) => {
fetching = false;
return [response, responseObj];
})
.catch(err => {
fetching = false;
return Promise.reject(err);
})
}
reducers / dataReducer.js
import { FETCHING_DATA, FETCHING_DATA_SUCCESS, FETCHING_DATA_FAILURE, EMPTY_DATA } from '../constants';
const initialState = {
data: [],
isFetching: false,
error: false,
}
export default dataReducer = (state = initialState, action) => {
switch (action.type) {
case EMPTY_DATA:
return {
...state,
data: []
}
case FETCHING_DATA:
return {
...state,
data: [],
isFetching: true
}
case FETCHING_DATA_SUCCESS:
if (action.initialData === null) {
return {
...state,
data: action.newData,
isFetching: false
}
} else {
let concatResult = {};
concatResult.total = action.newData.total;
concatResult.posts = action.initialData.posts.concat(action.newData.posts);
return {
...state,
data: concatResult,
isFetching: false
}
}
case FETCHING_DATA_FAILURE:
return {
...state,
isFetching: false,
error: true
}
default:
return state
}
}
也许这与我在dataReducer.js中进行concat的方式有关,我不知道这是否是处理Redux中更多负载的正确方式。 感谢您的阅读。
答案 0 :(得分:1)
我认为问题在于您创建新数据,而不是将其concat
替换为旧数据
concatResult.posts = action.initialData.posts.concat(action.newData.posts);
尝试进入concat
状态,例如
concatResult.posts = state.data.posts.concat(action.newData.posts);