【问题标题】:Avoid rerendering of FlatList row避免重新呈现 FlatList 行
【发布时间】:2018-05-23 05:33:04
【问题描述】:

我正在使用 React Native FlatList 在行上显示数据。以下是我的代码。

HomeScreen.js

render() {

    return (
      <View
        style={styles.container}
        onLayout={this.onLayout.bind(this)}>
        <Spinner visible={this.state.isShowSpinner} animation="fade" color={APP_THEME_COLOR} />
        <View style={styles.subContainerStyle}>

          {facetWebView}

          <AnimatedFlatList
            style={styles.flatListStyle}
            ref={flatListRef => this.templateFlatList = flatListRef}
            data={this.state.templatePosts}
            renderItem={({item}) => this.renderCellItem(item)}
          />
         </View>
         </View>
   } 

  renderCellItem(item, index) {

    return (
      <TemplateCell
        item={item}
        index={index}
        isPortraitMode={this.state.isPortraitMode}
        didSelectItemFromCell={(item) => {
          this.didSelectItemFromCell(item)
        }}
      />
    )
  }

在 TemplateCell 中,我显示了收藏/不收藏状态。我在 TemplateCell 中将 shouldComponentUpdate 写为

shouldComponentUpdate(nextProps, nextState) {

    const isItemChanged = this.props.item != nextProps.item
    const isPortraitMode = this.props.isPortraitMode != nextProps.isPortraitMode
    return isItemChanged || isPortraitMode
}

But still it is rendering the cell again. How can I avoid this. 

我在链接https://codeburst.io/when-to-use-component-or-purecomponent-a60cfad01a81中找到了

永不变异 你可能听说过不要在 props 和 state 中改变对象和数组。如果你要改变父组件中的对象,你的“纯”子组件不会更新。尽管上游的值发生了变化,但孩子会将引用与之前的道具进行比较,而不会检测到差异。

我相信我的数组是可变的,这就是为什么更改完成的项目对象在 props 和 nextProps 中保持不变。如何避免这种情况

【问题讨论】:

  • 如果您为您的FlatList 设置keyExtractor 会怎样,例如keyExtractor={(item, index) =&gt; item.UNIQUE_PROP}
  • @Cherniv keyExtractor={(item, index) => index}
  • 什么时候再渲染,cases?
  • @RaviRaj 1. 当我单击行上的按钮以更改收藏状态时 2. 当我为平面列表加载更多时 3. 当我在同一屏幕上显示其他 UI 时

标签: android ios performance react-native react-native-flatlist


【解决方案1】:

您的数组不是可变的。据我了解,当对其进行更改时,会按原样返回一个新数组。 这就是为什么通过引用检查在这里对您没有帮助的原因。您需要检查项目中的某些值。

例如:

shouldComponentUpdate(nextProps, nextState) {

  const isItemChanged = this.props.item.status != nextProps.item.status
  const isPortraitMode = this.props.isPortraitMode != nextProps.isPortraitMode
  return isItemChanged || isPortraitMode
}

【讨论】:

  • 感谢您的回复。实际上我的数组是可变的。当我检查 this.props.item.status 和 nextProps.item.status 时,我总是得到相同的值。
  • 那你可能有不同的问题。 Flatlist 是一个纯组件,如果您希望它更新,即使数组数据的长度没有改变,您应该按照文档 (facebook.github.io/react-native/docs/flatlist.html#extradata) 中的描述添加 extraData 属性。如果您的数组的长度没有变化,并且只有数组中的一项更改了其中一个值,那么您的平面列表将不会重新呈现
【解决方案2】:

我不确定这是否是最佳答案,但我设法解决了这个问题。我用过 deepcopy 库。

const newItem = deepcopy(item)
newItem.isFavorite = !item.isFavorite
const templates = this.state.templatePosts
var index = templates.indexOf(item)
templates.splice(index, 1, newItem);
this.setState({
  templatePosts: templates
})

现在,我可以使用了

shouldComponentUpdate(nextProps, nextState) {

    const isItemChanged = this.props.item != nextProps.item
    const isPortraitMode = this.props.isPortraitMode != nextProps.isPortraitMode
    return isItemChanged || isPortraitMode
}

【讨论】:

    猜你喜欢
    • 2022-01-25
    • 1970-01-01
    • 2021-06-16
    • 2020-05-16
    • 2021-11-29
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 2021-12-15
    相关资源
    最近更新 更多