【问题标题】:React-Native - Section List by keyReact-Native - 按键部分列表
【发布时间】:2019-08-08 07:34:07
【问题描述】:

我希望在 ReactNative 中显示分为多个部分的项目列表

从数据库接收的数据是一个平面数组,每个项目都有键 - 例如:

[{'key':'movie','name':'ToyStory1'},
 {'key':'movie','name':'ToyStory2'},
 {'key':'tv','name':'X-Files'},
 {'key':'tv','name':'Big bang theory'}]

我想保留一个平面阵列。

到目前为止,我发现所有使用此类数据的解决方案:

[{'key':'movie, 'data':[{'name':'ToyStory1'},{'name':'ToyStory2'}]},
 {'key':'tv, 'data':[{'name':'X-Files'},{'name':'Big bang theory'}]}
]

有什么想法吗?

【问题讨论】:

    标签: react-native react-native-flatlist


    【解决方案1】:

    您可以映射您的数据并在适当的位置插入“标题”对象。

    const data = [
      { 'key': 'movie', 'name': 'ToyStory1' },
      { 'key': 'movie', 'name': 'ToyStory2' },
      { 'key': 'tv', 'name': 'X-Files' },
      { 'key': 'tv', 'name': 'Big bang theory' }
    ];
    
    // preprocess data to insert header objects
    const dataWithHeadersInserted = data => data.reduce((res, item) => {
      if (item.key !== res.header) {
        res.header = item.key;
        res.data.push({ header: res.header });
      }
      res.data.push(item);
      return res;
    }, {
      header: null,
      data: [],
    }).data;
    
    const processedData = dataWithHeadersInserted(data);
    
    console.log(processedData);
    
    // later map over preprocessed data and render correct component
    // here in React you would use map and return components 
    // instead of forEach and console.log
    processedData.forEach(item => {
      if (item.header) {
        console.log('====== Header', item.header, '======');
      } else {
        console.log(item.name);
      }
    });

    如果您不想对数据进行预处理,您也可以即时进行:

    const data = [
      { 'key': 'movie', 'name': 'ToyStory1' },
      { 'key': 'movie', 'name': 'ToyStory2' },
      { 'key': 'tv', 'name': 'X-Files' },
      { 'key': 'tv', 'name': 'Big bang theory' }
    ];
         
    const dataWithHeadersOnFly = data => {
      let header = null;
    
      // In react this would be a map instead
      return data.forEach(item => {
        if (item.key !== header) {
          header = item.key;
          
          // In react you would return a Fragment with header and item components
          console.log('====== Header', header, '======');
          console.log(item.name);
          return;
        }
    
        // In react you would just return item component
        console.log(item.name);
      });
    };
    
    dataWithHeadersOnFly(data);
    const DataWithHeadersOnFly = ({data, renderSectionHeader, renderItem}) => {
      return data.map((item, index, dataArr) => (
        <Fragment>
          {(!dataArr[index - 1] || dataArr[index - 1].key !== item.key) && 
            renderSectionHeader({ header: item.key, index })}
          {renderItem({ item, index })}
        </Fragment>
      ));
    };
    
    ...
    
    render() {
      return (
        <DataWithHeadersOnFly
          data={data}
          renderSectionHeader={({ header, index }) => (
            <h3 key={`header-${header}-${index}`}>
              ====== {header} ======
            </h3>
          )}
          renderItem={({ item, index }) => (
            <div key={`${item.name}-${index}`}>{item.name}</div>
          )}
        />
      );
    }
    

    【讨论】:

    • 其实我是想避免改变数组,寻找可以解决这个问题的UI组件。
    • 这些都不会改变原始数组,map/reduce 返回新对象。 AFAIK 你可能不得不滚动你自己的组件来选择性地渲染部分。
    • @DrewReese- 这就是我要找的,一个 UI 组件
    • 我认为采用算法并制作一个反应组件是一个简单的练习;我已经修改了我的解决方案以包含一个正在运行的代码框。仅供参考,像这样的通用组件通常不会存在,因为它与您的数据模式高度耦合。另请注意,如果您想将每个“部分”包装在语义标签中,您可能必须使用类似于您的问题的嵌套结构,
    【解决方案2】:

    您可以创建一个函数来返回过滤后的对象数组,就像这样

    function filteredData(recievedData, key)
        { 
           var dataperKey = recievedData.filter(function (el) {
            return el.key == key
          });
          return dataperKey;
        }
    

    此函数将根据您传递的键返回过滤后的数组,例如,如果您将 movie 作为key 传递,则输出将是

    [{'key':'movie','name':'ToyStory1'},
     {'key':'movie','name':'ToyStory2'}]
    

    现在为`SectionList

    创建你的sections数据
    sections={[{'key':'movie, 'data':filteredData(recievedData,'movie')},
     {'key':'tv, 'data':filteredData(recievedData,'tv')}
    ]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-01
      • 2017-05-28
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多