【发布时间】:2019-06-26 08:35:58
【问题描述】:
我在一个组件中构建了一个非常复杂的列表,所有查询都以相同的方式进行。当我到达列表的末尾时,我将获取限制增加了 10... 一切都很顺利,直到我意识到我正在重新加载所有数据(不仅仅是新的 10 个)。我想避免所有这些读取以降低成本-我不确定firebase是否会忽略已加载的数据...当我每次获取额外的 10 个时,我的列表运行得非常顺利,但我不知道是否幕后的事情会回来困扰我!
更新
我根据一些有用的反馈更新了我的代码,我相信我的工作应该是这样的。我只关心一件事。当我在第一次获取后到达列表底部时,我会将所有以前的数据传递给我的动作创建者,然后将其连接到新获取的数据。随着列表的增长,每次我触底时都会重复这种情况。我的列表将有超过 1000 条记录,所以我担心潜在的性能问题,应该这样吗?在下面看看我的新尝试!
最初的尝试:
onEndReached = () => {
const { searchFilterText, effectVal } = this.state;
this.setState({
strainFetchIndex: this.state.strainFetchIndex + 10
}, () => {
const offset = this.state.strainFetchIndex;
if (searchFilterText === '') {
this.props.strainsFetch(offset);
} else if (searchFilterText === 'Hybrid' || searchFilterText === 'Salt' || searchFilterText === 'Initial') {
this.props.filterStrainAction(searchFilterText, offset);
} else if (searchFilterText === 'Effects') {
this.props.filterByEffect(effectVal, offset);
}
});
}
//HERES 1 of 4 ACTION CREATORS WHERE I FETCH MORE DATA (ALL ARE SIMILAR)
export const strainsFetch = (offset) => {
const ting = offset || 1;
return (dispatch) => {
firebase.database().ref('/strains')
.orderByKey()
.limitToFirst(1 * ting)
.on('value', snapshot => {
dispatch({ type: STRAINS_FETCH_SUCCESS, payload: snapshot.val() });
});
};
};
新尝试:
onEndReached = () => {
const { searchFilterText } = this.state;
const { lastKey } = this.props;
const currentStrains = this.props.strains;
if (this.state.filterLabel === 'Favourites') {
return null;
}
if (searchFilterText === '') {
//here I pass all previous records along with the last key (last key comes from my action creator)
this.props.strainsFetch(currentStrains, lastKey);
}
}
//ACTION CREATOR
export const strainsFetch = (currentStrains, lastKey) => {
if (!lastKey) {
return (dispatch) => {
// console.log('first Fetch');
firebase.database().ref('/strains')
.orderByKey()
.limitToFirst(10)
.on('value', snapshot => {
const snap = snapshot.val();
const snapKeys = Object.keys(snap);
const createLastKey = snapKeys[9];
dispatch({ type: STRAINS_FETCH_SUCCESS, payload: snapshot.val(), key: createLastKey });
});
};
}
return (dispatch) => {
// console.log('subsequent Fetch');
firebase.database().ref('/strains')
.orderByKey()
.startAt(`${lastKey}`)
.limitToFirst(11)
.on('value', snapshot => {
const snap = snapshot.val();
const snapKeys = Object.keys(snap)
.slice(1);
const results = snapKeys
.map((key) => snapshot.val()[key]);
const createLastKey = snapKeys[snapKeys.length - 1];
const concatStrains = _.concat(currentStrains, results);
dispatch({ type: STRAINS_FETCH_SUCCESS, payload: concatStrains, key: createLastKey });
});
};
};
//HERE IS WHAT MY REDUCER LOOKS LIKE
import {
STRAINS_FETCH_SUCCESS
} from '../actions/types';
const INITIAL_STATE = {};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case STRAINS_FETCH_SUCCESS:
// console.log(action.payload);
return { strains: action.payload, lastKey: action.key };
default:
return state;
}
};
随着列表的不断增长,一遍又一遍地将以前的数据传递给我的操作创建者,这是一种不好的做法吗?或者有没有更有效的方法来做到这一点?
谢谢大家!
干杯。
【问题讨论】:
-
您需要提供偏移量。您的第一次调用将在获取期间获取项目 0-10 - 后续请求将传递从第十个文档开始的
?offset=10。 -
嗨勒克斯,恐怕我不明白你想说什么。每次我的列表到达末尾时,我都会传入一个偏移量。每次加载比以前多 10 个项目时,它将偏移量增加 10。 @lux
-
用 Firebase 无限滚动是戏剧性的,因为需要以相反的顺序附加。例如:apps-script-community-ar-a9405.firebaseapp.com(注意右上角的数字)。如果我没记错的话,在随后的请求中,必须获取 10+1,但跳过 1。
-
谢谢马丁,你是对的......让它正常工作似乎很麻烦......你如何建议我得到最后一个钥匙作为我下一个起点获取?
标签: reactjs firebase firebase-realtime-database