首页 > 解决方案 > React Native FlatList 与可定制的道具(良好实践)

问题描述

这个问题是关于泛化组件时的良好实践和模式。

我正在实现一个 FlatList 包装器组件“UserList”,它呈现“UserListItem”。

我的想法是使其灵活,允许将“keyExtractor”或“renderItem”等自定义道具作为可选道具传递。如果没有传递 props,则列表将使用自己的方法。

所以,我有以下内容:

const UserList = memo(
  (props) => {
     const {
        data,
        keyExtractor,
        listKey,
        ListEmptyComponent,
        initialNumToRender,
        onRefresh,
        onEndReached,
     } = props;


     const _keyExtractor = useCallback((...) => ..., []);

     const _renderItem = useCallback((...) => ..., []);

     ...

     return (
        <FlatList
           ...
           keyExtractor={keyExtractor || _keyExtractor}
           renderItem={renderItem || _renderItem} 
           ...
           // some default configurations (updateCellsBatchingPeriod, windowSize, ...) for this type of component
        />    
  }
  (prevProps, nextProps) => { 
     ...
  }
);

像我一样实现列表和使用 defaultProps 定义默认的 keyExtractor 和 renderItem 有什么区别吗?

我的意思是,像这样:

UserList.defaultProps = {
  keyExtractor = (...) => ...,
  renderItem = (...) => ...
};

避免在组件内部定义。

另外,您是否考虑将可重用的 FlatLists 包装器组件作为一种好习惯?

制作另一个具有自己的 renderItem 和 keyExtractor 的 FlatList 包装器组件(避免我当前的 UserList 组件的泛化)是否会更专业、更容易阅读?

标签: javascriptreactjsreact-nativedesign-patterns

解决方案


与功能组件一起使用defaultProps并不经常(如果有的话),因为您可以直接在函数签名上定义默认/备用值。当您使用props对象的解构赋值时,这很容易。

const UserList = memo(
  ({
    data = [],
    keyExtractor = (...) => ...,
    renderItem = (...) => ...,
    listKey,
    ListEmptyComponent,
    initialNumToRender,
    onRefresh,
    onEndReached,
  }) => {
     ...

     return (
        <FlatList
           ...
           keyExtractor={keyExtractor}
           renderItem={renderItem} 
           ...
           // some default configurations (updateCellsBatchingPeriod, 
           //   windowSize, ...) for this type of component
        />    
  }
  (prevProps, nextProps) => { 
     ...
  }
);

另外,您是否考虑将可重用的 FlatLists 包装器组件作为一种好习惯?

React 被设计为使用组合,在这里封装和组合这些默认配置似乎是一个有效的用途。我会说,尽管您封装的更多组合和配置开始限制组件的通用性/可重用性。换句话说,它开始转向更具体的用例。

制作另一个具有自己的 renderItem 和 keyExtractor 的 FlatList 包装器组件(避免我当前的 UserList 组件的泛化)是否会更专业、更容易阅读?

我不认为仅仅为了这些道具中的一些需要或使用另一个平面列表组件,大多数平面列表组件 API 都足够通用。我认为如果您试图减少代码重复,将自定义renderItemkeyExtractor函数定义为一组可导入的实用程序(而不是每次都定义)会更有意义。


推荐阅读