如何在 React Native 中将更改应用于 Flatlist 中的单个元素

How to apply changes to a single element in a Flatlist in React Native

我有一个呈现多个 post 的 Flatlist,每个 post 都有一个文本部分,文本可能会变得非常大,所以我使用 show more 方法 expand/hide 文本,我正在使用状态处理它的状态,但是,当我单击 post 展开文本时,它会展开 Flatlist 中的所有 post,我尝试创建每个 post 的动态 Ref,但我想不出相应地更改文本内容的方法,我遗漏了什么?

这是我的代码:

  const [showMore, setShowMore] = useState(false);

  const refs = useRef([]);




// Inside a Flatlist render item: 

    <View style={styles.postContainer}>
      {item.data.postText.length > 120 ? (
        showMore ? (
          <TouchableOpacity onPress={() => setShowMore(!showMore)}
           ref={(expandableText) => (refs.current[index] = expandableText)}>
            <Text style={styles.postDescription}>{item.data.postText}</Text>
            <Text style={styles.seeMore}>Show less</Text>
          </TouchableOpacity>
        ) : (
          <TouchableOpacity onPress={() => setShowMore(!showMore)}>
            <Text style={styles.postDescription}>
              {`${item.data.postText.slice(0, 120)}... `}
            </Text>
            <Text style={styles.seeMore}>Show more</Text>
          </TouchableOpacity>
        )
      ) : (
        <Text style={styles.postDescription}>{item.data.postText}</Text>
      )}
    </View>

您对 FlatList 的所有项目使用相同的状态。因此,如果您更改状态,所有项目都将展开。您可以将布尔数组保留为状态。这个状态数组的索引对应于flatlist里面的一个组件的索引。

// data is the data of your FlatList
// we use this to initialize each show more value with false
const [showMore, setShowMore] = useState(data.map(data => false))

在您的渲染函数中,您可以按如下方式使用它。

renderItem={({item, index}) => {
 return <View style={styles.postContainer}>
      {item.data.postText.length > 120 ? (
        showMore[index] ? (
          <TouchableOpacity onPress={() => handleShowMore(index)}
           ref={(expandableText) => (refs.current[index] = expandableText)}>
            <Text style={styles.postDescription}>{item.data.postText}</Text>
            <Text style={styles.seeMore}>Show less</Text>
          </TouchableOpacity>
        ) : (
          <TouchableOpacity onPress={() => handleShowMore(index)}>
            <Text style={styles.postDescription}>
              {`${item.data.postText.slice(0, 120)}... `}
            </Text>
            <Text style={styles.seeMore}>Show more</Text>
          </TouchableOpacity>
        )
      ) : (
        <Text style={styles.postDescription}>{item.data.postText}</Text>
      )}
    </View>
}

handleShowMore函数如下

function handleShowMore(index) {
    setShowMore(prev => prev.map((element, idx) => {
        if(idx === index) {
            return !element
        }
        return element
   }))
}