Search code examples
react-nativereact-native-paperreact-native-component

React Native Datatable doesn't show after moving the fragment into Component


I've created the following component. React Native Paper Datatable rows aren't showing after moving it into component and linking it to json loop.

If we comment " and uncommented the commented block below, you will see the Datatable is showing. What am I doing wrong with my two components? I've done all console.log. All data are showing correctly but JSX elements aren't rendering inside Datatable.

I've created the following code on Snack: https://snack.expo.dev/@everestster/datatable-component

import React, {useEffect} from 'react';
import type {Node} from 'react';
import {View, ScrollView, Text, StyleSheet, Dimensions} from 'react-native';
import {DataTable as PaperDataTable} from 'react-native-paper';

const DataTable = props => {
  const optionsPerPage = [2, 3, 4];
  const [page, setPage] = React.useState(0);
  const [itemsPerPage, setItemsPerPage] = React.useState(optionsPerPage[0]);
  useEffect(() => {
    setPage(0);
  }, [itemsPerPage]);

  const HeaderSection = (): Node => {

    console.log(props.items);
    if (props.items.length === 0) {
      return;
    }
    return (
      <PaperDataTable.Header>
        {Object.keys(props.items[0]).forEach(function (key) {
          if (key !== 'Id') {
            <PaperDataTable.Title style={[styles.allCell]}>
              {key}
            </PaperDataTable.Title>;
          }
        })}
      </PaperDataTable.Header>
    );
  };

  const BodySection = (): Node => {
    return (
      <PaperDataTable.Row>
        {Object.keys(props.items[0]).forEach(function (key) {
          if (key !== 'Id') {
            <PaperDataTable.Cell style={[styles.allCell]}>
              {key}
            </PaperDataTable.Cell>;
          }
        })}
      </PaperDataTable.Row>
    );
  };

  return (
    <ScrollView style={styles.tableHolder}>
      <ScrollView horizontal={true}>
        <View style={{alignItems: 'center'}}>
          <PaperDataTable style={styles.table}>
            <HeaderSection />
            <BodySection />
            {/*<PaperDataTable.Header>
              <PaperDataTable.Title>Name</PaperDataTable.Title>
              <PaperDataTable.Title>Email</PaperDataTable.Title>              
            </PaperDataTable.Header>

            <PaperDataTable.Row>
              <PaperDataTable.Cell>John</PaperDataTable.Cell>
              <PaperDataTable.Cell>[email protected]</PaperDataTable.Cell>
            </PaperDataTable.Row>

            <PaperDataTable.Row>
              <PaperDataTable.Cell>Harry</PaperDataTable.Cell>
              <PaperDataTable.Cell>[email protected]</PaperDataTable.Cell>              
            </PaperDataTable.Row>

            <PaperDataTable.Row>
              <PaperDataTable.Cell>Jessica</PaperDataTable.Cell>
              <PaperDataTable.Cell>[email protected]</PaperDataTable.Cell>              
            </PaperDataTable.Row>*/}
            <PaperDataTable.Pagination
              page={page}
              numberOfPages={1}
              onPageChange={p => setPage(p)}
              optionsPerPage={optionsPerPage}
              itemsPerPage={itemsPerPage}
              setItemsPerPage={setItemsPerPage}
              showFastPagination
              optionsLabel={'Rows per page'}
            />
          </PaperDataTable>
        </View>
      </ScrollView>
    </ScrollView>
  );
};
const styles = StyleSheet.create({
  tableHolder: {},
  table: {
    paddingLeft: 50,
    paddingRight: 50,
    flex: 1,
  },
  allCell: {
    marginRight: 20,
  },
});

export {DataTable};

Any help will be appreciated.


Solution

  • The problem is in your structure. Your current BodySection is not returning the correct structure react-native-paper wants. I rewrote the BodySection function. Here is the snack: https://snack.expo.dev/@truetiem/datatable-component

      const BodySection = (): Node => {
        return props.items.map(function (item) {
          return (
            <PaperDataTable.Row>
              {Object.keys(item).map((key) => key === 'Id' ? null : (
                <PaperDataTable.Cell>
                  {item[key]}
                </PaperDataTable.Cell>
              ))}
            </PaperDataTable.Row>
          );
        });
      };