Home > database >  Error when trying to generate dynamic table content: Objects are not valid as React child
Error when trying to generate dynamic table content: Objects are not valid as React child

Time:10-02

I am quite new with React Native and one thing is not working for me which I'd expect to work. Maybe someone can tell me where I'm wrong or advise the correct way to go.

I have certain data which can be represented as a table. With arbitrary amount/names of columns. So I want to draw a dynamic table in the app.

The example of data looks like this:

{
    "columns": ["column1", "column2"],
    "results": [
        {"column1": "test", "column2": "passed"},
        {"column1": "second test", "column2": "passed as well"}
    ]
}

Thus, I would like to draw a table (for example via DataTable from react-native-paper, though it can be any other kind of table) such as this one:

<DataTable>
  <DataTable.Header>
    <DataTable.Title>column1</DataTable.Title>
    <DataTable.Title>column2</DataTable.Title>
  </DataTable.Header>

  <DataTable.Row>
    <DataTable.Cell>test</DataTable.Cell>
    <DataTable.Cell>passed</DataTable.Cell>
  </DataTable.Row>

  <DataTable.Row>
    <DataTable.Cell>second test</DataTable.Cell>
    <DataTable.Cell>passed as well</DataTable.Cell>
  </DataTable.Row>
</DataTable>

So what I am doing now is: (the code is simplified to show the matter)

const drawTable = (data) => {
    const result = JSON.parse(data)

    let content = `<DataTable><DataTable.Header>`
    result.columns.forEach(function(element, idx, array) {
        content  = `<DataTable.Title>${element}</DataTable.Title>`
    })
    content  = `</DataTable.Header>`
  
    result.results.forEach(function (element, idx, array) {
        content  = `<DataTable.Row>`
        result.columns.forEach(function (column, idx, array) {
            content  = `<DataTable.Cell>${element[column]}</DataTable.Cell>`
        })
        content  = `</DataTable.Row>`
    })

    content  = `</DataTable>`
    return (
        {content}
    )
}

const HomeScreen = (props) => {
    const [data, setData] = React.useState(null)
    <View>
        {drawTable(data)}  //here the data is already a valid JSON with format as mentioned above
    </View>

}

And what I get is the following error:

Objects are not valid as a React child (found: object with keys {content}). If you meant to render a collection of children, use an array instead.

So basically I want to generate a component from a string that is built dynamically. What is the proper way to do that?

Thanks!

CodePudding user response:

Try this, avoid use the idx as key, i use only for practical purposes.

import * as React from 'react';
import { Text, View, StyleSheet, SafeAreaView } from 'react-native';
import Constants from 'expo-constants';

// You can import from local files
import AssetExample from './components/AssetExample';

// or any pure javascript modules available in npm
import { Card, DataTable } from 'react-native-paper';

export default function App() {
  const data = {
    columns: ['column1', 'column2'],
    results: [
      { column1: 'test', column2: 'passed' },
      { column1: 'second test', column2: 'passed as well' },
    ],
  };

  const { columns, results } = data;

  return (
    <SafeAreaView style={styles.container}>
      <DataTable>
        <DataTable.Header>
          {columns.map((column, idx) => (
            <DataTable.Title key={column}>{column}</DataTable.Title>
          ))}
        </DataTable.Header>
        {results.map((result, idx) => (
          <DataTable.Row key={idx}>
            <DataTable.Cell>{result.column1}</DataTable.Cell>
            <DataTable.Cell>{result.column2}</DataTable.Cell>
          </DataTable.Row>
        ))}
      </DataTable>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ecf0f1',
    paddingTop: 50,
  },
});

Here is a snack: https://snack.expo.dev/MnkVd6B1e, you can run it with expo

  • Related