【问题标题】:React native Flatlist not re-rendering on state changeReact native Flatlist 不会在状态更改时重新渲染
【发布时间】:2021-09-15 17:10:18
【问题描述】:

我意识到有很多关于这个的问题和答案,但我对 react native 还很陌生,大多数答案都是关于 React 组件而不是钩子。在以下示例中,availableInterests 是从 firestore 数据库调用中提取的。然后我们遍历 availableInterests,以便用户可以从 Flatlist of Interests 中选择他们的兴趣。一切都很好,除了 FLatlist 不会重新渲染,因此用于选择 currentInterests 的按钮永远不会显示已选择兴趣的更改。有人看到我在这里缺少什么吗?

const [availableInterests, setAvailableInterests] = useState([]);
const [currentInterests, setCurrentInterests] = useState([]);
    const selectThisInterest = (item) => {
        let myInterests = currentInterests;
        if(myInterests.includes(item.id)) {
          myInterests.pop(item.id);
        } else {
          myInterests.push(item.id);
        }

        setCurrentInterests(myInterests);
      }

  return <View>
    <Text style={styles.text}>Select Your Interests:</Text>
      <FlatList
       data={availableInterests}
       keyExtractor={(item, index) => index.toString()}
       extraData={currentInterests}
       renderItem={({ item, index }) => 
         <View key={item.id}>
           <Text>{item.title}</Text>
           <Text>{item.description}</Text>
           <Image
            source={{ uri: item.icon }}
            style={{ width: 100, height: 100}}
           />
         <TouchableOpacity onPress={() => selectThisInterest(item)}>
           <Text style={styles.buttonText}>{`${currentInterests.includes(item.id) ? 'UnSelect' : 'Select'}`}</Text>
           <Text>{item.id}</Text>
         </TouchableOpacity>
        </View>
      }>
    </FlatList>
</View>

【问题讨论】:

    标签: react-native react-hooks react-native-flatlist


    【解决方案1】:

    把这个状态放在下面

    const [currentInterests, setCurrentInterests] = useState([]);
    const [extra, setExtra] = useState(0);
    

    在你的函数末尾放这个

        const selectThisInterest = (item) => {
        ....
    
        setExtra(extra + 1)
      }
    

    【讨论】:

    • 我试试这个,但它仍然没有改变。我认为这是因为我每次都在更改 currentInterests 的状态,这会导致刷新。但到目前为止,这些都没有这样做。
    • 实际上,我需要添加 extra 作为 extraData 所以... extraData={extra} 然后它就可以工作了。如果您想将其添加到您的答案中,我将接受作为正确答案。 :) 我想知道 currentInterests 更改是否不会强制重新渲染,因为它是一个数组?
    • 你可以使用 extraData 属性并给它状态
    • @Starfs 不,因为您在 Flatlist 中使用的是已经呈现的状态,至少这是我的理解。欢迎任何人纠正我。作为一个好的做法,我们被告知要添加这个额外的 useState,所以我们永远不会提出这个问题。
    【解决方案2】:

    我认为错误出在您的 selectThisInterest 函数中。当您根据先前的值更新 currentInterests 时,React 无法识别此类更改,因为您只是将 myInterests 分配给您的 currentInterests

    您要做的是复制该数组并将其分配给myInteresets,然后将您的值更新为新复制的数组。在新的 myInteresets 数组上完成计算后,setCurrentInterests() 将重新渲染应用程序,因为现在 React 识别出状态发生了变化。

    要复制数组,可以使用,

    let myInterests = [...currentInterests];
    

    更改您的 selectThisInterest 函数以反映此更改,

    const selectThisInterest = (item) => {
      let myInterests = [...currentInterests];
      if(myInterests.includes(item.id)) {
        myInterests.pop(item.id);
      } else {
        myInterests.push(item.id);
      }
      setCurrentInterests(myInterests);
    }
    

    【讨论】:

      猜你喜欢
      • 2018-12-27
      • 2020-03-10
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 2018-12-27
      • 2020-10-03
      相关资源
      最近更新 更多