有没有比遍历json数组更快的方法来更新json数组?

时间:2019-03-31 11:27:31

标签: javascript node.js json react-native expo

直到博览会让我使用Realm数据库ive决定与Json和asyncstorage一起使用。源数据仍然来自Json,因此对于此应用程序,将其保留为json是有意义的。

我有一个带有json的单位列表。列表中每个项目的左侧是一个星形图标。

当我触摸列表中的每个项目时,星标将变实,表明已被按下。再按一次,该图标将是星星的轮廓,表明它已被取消选择。

onpress函数看起来像这个符号是JSON数据的名称,JSON数据具有3个键... symbol,name和iconName。符号是要触摸的平板列表中的项目。

onPressListItem = ( symbol ) => {
    for (var i = 0; i < this.state.symbols.length; i++){
        if (this.state.symbols[i].symbol === symbol){
            const copyOfSymbolsList = [...this.state.symbols];
            if (copyOfSymbolsList[i].iconName === 'md-star') {
                copyOfSymbolsList[i].iconName = 'md-star-outline';
            } else {
                copyOfSymbolsList[i].iconName = 'md-star';    
            }

            this.setState({ symbols:copyOfSymbolsList });
        }
    }
}

因此,正如您在上面看到的那样,基本上只是滚动整个json数组以找到合适的行,然后制作列表的副本,更改数据,然后再次设置状态。

在像素2上的图标更改之前,该应用程序并非超级快,可能延迟了半秒,并且列表中只有100条记录。我有点担心列表是否进入数千行,这真的很糟糕。

是否有更好/更快/更简单/更多反应方式来解决此问题?

编辑

这是renderListItem函数,它调用onPress函数

renderListItem = ({ item }) => {
    return (
        <TouchableOpacity
            onPress={() => this.onPressListItem(item.symbol)}
        >
            <View style={{flex: 1, flexDirection: 'row'}}>
                <View style={{backgroundColor: 'powderblue'}}>
                    <Ionicons style={styles.listItemIcon} name={item.iconName} />
                </View>
                <View style={{backgroundColor: 'skyblue'}}>
                    <Text style={styles.listItem}>
                        {item.name.toUpperCase()} {item.symbol}
                    </Text>
                </View>
            </View>
        </TouchableOpacity>
    );
};

编辑#2 这是FlatList代码。

<View style={styles.mainContainer}>
                <FlatList
                    data={this.state.symbols}
                    keyExtractor= {(item, index) => item.symbol}
                    ItemSeparatorComponent={this.renderListSeparator}
                    renderItem={this.renderListItem}
                />
            </View>

2 个答案:

答案 0 :(得分:0)

我来宾,您的json结构是这样的。

  the_data =  [
     {'iconName': 'xxx', 'symbol': '<i class="fa fa-items"></i>'}
    ]

您可以通过索引访问此结构,并将索引传递给onPressListItem函数。

renderListItem = ({ item }, index) => {
    return (
        <TouchableOpacity
            onPress={() => this.onPressListItem(index)}
        >
            <View style={{flex: 1, flexDirection: 'row'}}>
                <View style={{backgroundColor: 'powderblue'}}>
                    <Ionicons style={styles.listItemIcon} name={item.iconName} />
                </View>
                <View style={{backgroundColor: 'skyblue'}}>
                    <Text style={styles.listItem}>
                        {item.name.toUpperCase()} {item.symbol}
                    </Text>
                </View>
            </View>
        </TouchableOpacity>
    );
};

通过这种设计,您不必迭代json。

onPressListItem = ( index ) => {
   the_dataobj = the_data[index];
   the_dataobj.iconName = 'md-start';
   if (the_dataobj.iconName === 'md-start'){
     the_dataobj.iconName = 'md-start_outline';
   }
   //you don't need a extra else here, is in-necesarry
   the_data[index] = the_dataobj;
   //set state ... do more
}

顺便说一句:这与反应无关,您的工作流程的正确设计应独立于框架库。

祝您生日快乐!

答案 1 :(得分:0)

对于您阅读的那些人,接受的答案未正确更新屏幕上的呈现列表。所以下面是我的实际工作代码。我很确定是因为接受的答案没有使用this.setState函数将值写回到数组。

如果if else则需要在其中包含else,因为当用户两次敲击同一行时,我希望它撤消其更改。

所有这些,更新仍然非常缓慢。与在问题中使用for循环时的速度大致相同。不知道为什么。

onPressListItem = ( index ) => {
        const copyOfSymbolsList = [...this.state.symbols];
        thePressedSymbol = copyOfSymbolsList[index];

        if (thePressedSymbol.iconName === 'md-star') {
            thePressedSymbol.iconName = 'md-star-outline';
        }else{
            thePressedSymbol.iconName = 'md-star';
        }
        copyOfSymbolsList[index] = thePressedSymbol;
        this.setState({ symbols:copyOfSymbolsList });
    }