我在这里见证了一些魔法。
首先,这是一个相当常见的问题,相信我,我已经做过研究,所以请在将其标记为重复之前,请听我说完。
数组和对象之间的性能差异已经在这个SO答案中被很好地解释了,我已经将其应用到我的React Native应用程序中,希望它能将我的性能提高约300%。但结果是一个巨大而令人失望的惊喜。
我将数据结构从对象数组改变为...
现在如果我想访问一个对象,而不是通过循环数组并测试其属性(例如id),我可以直接这样做:
无论如何,我都没有看到任何理由不这样做。所以现在我想分享我的源代码(React Native),因为我怀疑问题可能出在我的实现方式上。
以下是我的数据: poems.json:
这是我的 reducer: poemReducer.js
我做错了什么吗?我对整体想法有什么不理解的地方吗?
非常感谢您提供任何见解。
编辑
如果浪费了任何人的时间,我很抱歉。我意识到我在应用程序的完全不同部分犯了一个错误。在负责渲染诗歌的React Native组件中,我做了以下操作:
首先从redux获取诗歌:
首先,这是一个相当常见的问题,相信我,我已经做过研究,所以请在将其标记为重复之前,请听我说完。
数组和对象之间的性能差异已经在这个SO答案中被很好地解释了,我已经将其应用到我的React Native应用程序中,希望它能将我的性能提高约300%。但结果是一个巨大而令人失望的惊喜。
我将数据结构从对象数组改变为...
let poems = [ obj1, obj2, ..., obj64]
将对象的键设置为对象id
,值设置为整个对象本身
let poems = { "obj1_id": obj1, "obj2_id": obj2, ...}
现在如果我想访问一个对象,而不是通过循环数组并测试其属性(例如id),我可以直接这样做:
poems[obj1_id]
,这将更为高效(就速度而言)。无论如何,我都没有看到任何理由不这样做。所以现在我想分享我的源代码(React Native),因为我怀疑问题可能出在我的实现方式上。
以下是我的数据: poems.json:
{
"Family": {
"1": {
"id": "1",
"category": "Family",
"favorite": false,
"body": "Poem 1"
},
.
.
.
"64": {
"id": "64",
"category": "Family",
"favorite": false,
"body": "Poem 64"
}
}
}
这是我的 reducer: poemReducer.js
import all_poems from '../data/poems_obj.json';
const initialPoems = {
allPoems: all_poems,
currentPoems: {},
favoritePoems: {}
};
export default poems = (state = initialPoems, action = {}) => {
switch (action.type) {
case SET_POEMS:
return state;
case SET_CURRENT_POEMS:
return {
...state,
currentPoems: state.allPoems[action.name]
};
case TOGGLE_FAVORITE:
let currentPoems = state.currentPoems;
let favoritePoems = state.favoritePoems;
let poem = currentPoems[action.id];
poem.favorite = !poem.favorite;
if (poem.favorite) {
favoritePoems[poem.id] = poem;
} else {
delete favoritePoems[poem.id]
}
return { ...state, currentPoems, favoritePoems };
default: return state;
}
}
信不信由你,当我点击收藏按钮来切换诗歌收藏的布尔值时,大约需要 9s
的时间。不是9毫秒,而是9 秒,在只有64个对象大小的对象中。
这是我如何分派动作的:
export const toggleFavorite = (id) => {
return {
type: TOGGLE_FAVORITE,
id
};
}
我做错了什么吗?我对整体想法有什么不理解的地方吗?
非常感谢您提供任何见解。
编辑
如果浪费了任何人的时间,我很抱歉。我意识到我在应用程序的完全不同部分犯了一个错误。在负责渲染诗歌的React Native组件中,我做了以下操作:
首先从redux获取诗歌:
mapStateToProps = (state) => { poems: state.poems.currentPoems }
由于诗歌在redux中以对象的形式存在,因此这些诗歌的格式如下:
{
"1": {
"id": "1",
"category": "Family",
"favorite": false,
"body": "Poem 1"
},
.
.
.
"64": {
"id": "64",
"category": "Family",
"favorite": false,
"body": "Poem 64"
}
}
我正在React Native的FlatList
组件中呈现此内容,因此我需要这些数据成为对象数组。所以为了将对象转换为对象数组,在我的render()
方法中的return
语句之前,我会进行如下操作:
const { poems } = this.props; // grab from redux, via mapStateToProps function
const poemsArr = Object.keys(poems).map(key => peoms[key]); // change into array of objects
然后我将poemsArr
作为值传递给我的Flatlist组件的data
属性。
<FlatList
data={poemsArr}
renderItem={this.renderItem}
/>
某种方式,这严重拖慢了我的应用程序。
现在我做出的改变是,在render()
方法内部将我的对象转换为对象数组的代替方式是直接在mapStateToProps()
方法中进行转换:
mapStateToProps = (state) => { poems: Object.keys(currentPoems).map(key => currentPoems[key]) }
这解决了我的问题。目前我还没有一个良好的解释为什么它起作用。这是我现在的任务。
如果这浪费了任何人的时间,我很抱歉。感谢你们的贡献。它们真的帮助了我。
附言:在发布之前,我对原始源代码进行了许多修改,以使其通用和简单。由于我只是初学JavaScript开发者,可能会有一些语法错误。谢谢
[<>]
工具栏按钮)。Stack Snippets 支持 React,包括 JSX;这里是如何创建一个。 - T.J. Crowder