【问题标题】:React native flatlist multiple selection is not updating反应本机平面列表多选未更新
【发布时间】:2020-11-07 16:02:14
【问题描述】:

我正在使用平面列表来公开我保存在数据库中的所有成分列表,但是一旦我更新了状态,它就不会反映在平面列表组件上。

平面列表组件

<FlatList
  horizontal
  bounces={false}
  key={ingredientList.id}
  data={ingredientList}
  renderItem={({ item }) => (
    <TouchableOpacity onPress={() => selectedIngredient(item)}>
      <Card key={item.id}>
        <Text key={item.title} style={styles.titleText}>{item.name}</Text>
        <Text key={item.title} style={styles.titleText}>{item.isSelected?'selected':'not selected'} 
        </Text>
        <ImageBackground key={item.illustration} source={item.illustration} style={styles.cardImage}> 
        </ImageBackground>
      </Card>
    </TouchableOpacity>
  )}
  keyExtractor={(item) => item.index}
/>

这是查找所选项目“selectedIngredient”的功能

function selectedIngredient(item) {
    console.log('received: ', item.name)
    item.isSelected = !item.isSelected;
    return { ...item.isSelected }
}

当我在“item.isSelected = !item.isSelected”之后尝试使用 console.log 调试时,该组件调用正在工作,但 IU 未更新。有人可以帮助我了解如何解决它吗?

【问题讨论】:

    标签: javascript react-native react-native-flatlist


    【解决方案1】:

    您需要在基于类的组件中使用setState 或在功能组件中使用useState 挂钩来设置状态。

    function selectedIngredient(item) {
        console.log('received: ', item.name)
        item.isSelected = !item.isSelected; //this is not how you set state
        return { ...item.isSelected }
    }
    
    

    截图:

    这是我为您当前场景修改的旧示例:

    import React, { useState } from 'react';
    import {
      Text,
      View,
      StyleSheet,
      FlatList,
      TouchableOpacity,
    } from 'react-native';
    import Constants from 'expo-constants';
    
    // You can import from local files
    
    // or any pure javascript modules available in npm
    
    const ingredientList = [
      {
        id: 1,
        name: 'item1',
        selected: false,
      },
      {
        id: 2,
        name: 'item 2',
        selected: false,
      },
      {
        id: 3,
        name: 'item 3',
        selected: false,
      },
      {
        id: 8,
        name: 'item 4',
        selected: false,
      },
      {
        id: 4,
        name: 'item 5',
        selected: false,
      },
      {
        id: 5,
        name: 'item 6',
        selected: false,
      },
    ];
    
    export default function App() {
      const [selectedItem, setSelectedItem] = useState(null);
      const [allItems, setAllItems] = useState(ingredientList);
    
      const selectedIngredient = (item) => {
        console.log('selecionado: ' + item.name);
        setSelectedItem(item);
        /* Below operation can be improved by passing index to the function itself.
           so filtering would not be required
         */
        let temp = allItems.filter((parentItem) => parentItem.id !== item.id);
        item.selected = !item.selected;
        temp = temp.concat(item);
        temp.sort((a, b) => parseInt(a.id) - parseInt(b.id));
        setAllItems(temp);
        console.log(allItems);
      };
      return (
        <View style={styles.container}>
          <FlatList
            style={styles.flatlist}
            horizontal
            bounces={false}
            data={allItems}
            renderItem={({ item }) => (
              <TouchableOpacity
                style={styles.flatListItem}
                key={item.id}
                onPress={() => selectedIngredient(item)}>
                <Text>{item.name}</Text>
                {!item.selected ? (
                  <Text style={{ color: 'red' }}>{'Not Selected'}</Text>
                ) : (
                  <Text style={{ color: 'green' }}>{'Selected'}</Text>
                )}
              </TouchableOpacity>
            )}
            keyExtractor={(item) => item.index}
          />
    
          {selectedItem ? (
            <View style={styles.selectedTextView}>
              <Text style={styles.selectedText}>{`${selectedItem.name} ${
                selectedItem.selected ? 'selected' : 'not selected'
              }`}</Text>
            </View>
          ) : (
            <View style={styles.selectedTextView}>
              <Text style={styles.selectedText}>{`Nothing selected`}</Text>
            </View>
          )}
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
        padding: 8,
      },
      flatListItem: {
        width: 100,
        height: 100,
        backgroundColor: 'white',
        margin: 5,
        borderRadius: 10,
        justifyContent: 'center',
        alignItems: 'center',
      },
      selectedTextView: {
        flex: 8,
        backgroundColor: 'white',
        margin: 5,
        borderRadius: 10,
        justifyContent: 'center',
        alignItems: 'center',
        fontSize: 20,
      },
      selectedText: {
        fontSize: 30,
      },
    });
    
    

    Live Demo

    【讨论】:

    • 你的例子正是我需要的,但是当我用这个结构更新我的代码时,当组件安装时,“ingredientList”没有更新“allItems”状态,它只显示初始状态。所选值有效,但不在数据集上。你知道为什么会这样吗?当我使用 console.log 查看“ingredientList”时,它具有相应的值。
    • 我可以获取您尝试对其执行状态修改的数据,即ingredientList吗?关于您的代码为何如此运行,我必须查看整个相关代码...尝试查看上面的示例并自己尝试一段时间:) 这是一项相对简单的任务,您可以一旦你理解了上面的例子,就实现它。
    • 我会尝试像你一样实现并重构组件。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多