在功能组件中使用 React.memo 来渲染Item FlatList,以最大程度地减少重新渲染现有项目

wid*_*ayd 7 reactjs react-native

我正在使用功能组件,并使用 Flatlist 来渲染数据列表,它工作正常,但是每次状态获取附加数据时,它总是重新渲染现有数据,这会导致性能问题,我已经阅读了这些文章,但仍然有没有线索

这是我使用 main Flatlist 的代码

<FlatList
  horizontal={false}
  showsHorizontalScrollIndicator={false}
  data={users}
  keyExtractor={(item, index) => String(index)}
  renderItem={RenderUser}
  onEndReachedThreshold={0.7}
  onEndReached={callBackMoreData}
/>
Run Code Online (Sandbox Code Playgroud)

这里正在工作 RenderUser 但问题是如果状态有附加数据,它会重新渲染现有项目,我想要实现的只是渲染附加数据

import React from 'react';
import { ListItem } from 'react-native-elements';

const RenderUser = ({ item, index }) => {

  return (
    <React.Fragment>
      { console.log('index: ', index)}
      <ListItem 
        title={item.attributes.name}
      />
    </React.Fragment>
  );
};

export default RenderUser;
Run Code Online (Sandbox Code Playgroud)

我确实尝试使用下面的代码(但我收到一条错误消息,指出 TypeError: renderItem is not a function. (in 'renderItem(props)', 'renderItem' is an instance of object))

import React, { memo } from 'react';
import { ListItem } from 'react-native-elements';

const RenderUser = ({ item, index }) => {

  return (
    <React.Fragment>
      { console.log('index: ', index)}
      <ListItem 
        title={item.attributes.name}
      />
    </React.Fragment>
  );
};

export default memo(RenderUser);
Run Code Online (Sandbox Code Playgroud)

Shu*_*rma 6

根据react官方文档:

默认情况下,它只会浅层比较 props 对象中的复杂对象。如果您想控制比较,您还可以提供自定义比较函数作为第二个参数

function MyComponent(props) {
  /* render using props */
}
function areEqual(prevProps, nextProps) {
  /*
  return true if passing nextProps to render would return
  the same result as passing prevProps to render,
  otherwise return false
  */
}
export default React.memo(MyComponent, areEqual);
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您需要添加条件:

import React, { memo } from 'react';
import { ListItem } from 'react-native-elements';

const RenderUser = ({ item, index }) => {

  return (
    <React.Fragment>
      { console.log('index: ', index)}
      <ListItem 
        title={item.attributes.name}
      />
    </React.Fragment>
  );
};

function arePropsEqual(prevProps, nextProps) {
      /*
      return true if passing nextProps to render would return
      the same result as passing prevProps to render,
      otherwise return false
      */
      return nextProps.item.attribute.name===prevProps.item.attribute.name
    }

export default memo(RenderUser,arePropsEqual);

Run Code Online (Sandbox Code Playgroud)

注意:不确定您获得了多少道具以及哪些道具是独特的。基本上你需要比较最后一个是否等于这个返回 true,这样反应就不会重新渲染你的组件