Home > Mobile >  react-table Uncaught TypeError: columns.map is not a function
react-table Uncaught TypeError: columns.map is not a function

Time:04-24

I am writing the react-table getting started with typescript, however I am getting an error on the data I am passing into my table function:

utils.js:15 Uncaught TypeError: columns.map is not a function
    at linkColumnStructure (utils.js:15:1)
    at useTable.js:150:1
    at mountMemo (react-dom.development.js:17057:1)
    at Object.useMemo (react-dom.development.js:17517:1)
    at Object.useMemo (react.development.js:1645:1)
    at useTable (useTable.js:149:1)
    at Table (App.tsx:9:1)
    at renderWithHooks (react-dom.development.js:16141:1)
    at mountIndeterminateComponent (react-dom.development.js:20838:1)
    at beginWork (react-dom.development.js:22342:1)

Being new to react/typescript pointers much appreciated on my App.tsx below, if I comment out the Table function the page loads, so I am doing something wrong with my types just not sure what.

import React from 'react';
import { useTable } from 'react-table';
import logo from './logo-main.svg';
import './App.css';

function Table(columns: any, data: any) : any
{
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({ columns, data });

  // Render the UI for your table
  return (
    <table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
    <thead>
      {headerGroups.map(headerGroup => (
        <tr {...headerGroup.getHeaderGroupProps()}>
          {headerGroup.headers.map(column => (
            <th
              {...column.getHeaderProps()}
              style={{
                borderBottom: 'solid 3px red',
                background: 'aliceblue',
                color: 'black',
                fontWeight: 'bold',
              }}
            >
              {column.render('Header')}
            </th>
          ))}
        </tr>
      ))}
    </thead>
    <tbody {...getTableBodyProps()}>
      {rows.map(row => {
        prepareRow(row)
        return (
          <tr {...row.getRowProps()}>
            {row.cells.map(cell => {
              return (
                <td
                  {...cell.getCellProps()}
                  style={{
                    padding: '10px',
                    border: 'solid 1px gray',
                    background: 'papayawhip',
                  }}
                >
                  {cell.render('Cell')}
                </td>
              )
            })}
          </tr>
        )
      })}
    </tbody>
  </table>
  )
}

function App() {

  const data = React.useMemo(
    () => [
      {
        col1: 'Hello',
        col2: 'World',
      },
      {
        col1: 'react-table',
        col2: 'rocks',
      },
      {
        col1: 'whatever',
        col2: 'you want',
      },
    ],
    []
  )

  const columns = React.useMemo(
    () => [
      {
        Header: 'Column 1',
        accessor: 'col1', // accessor is the "key" in the data
      },
      {
        Header: 'Column 2',
        accessor: 'col2',
      },
    ],
    []
  )

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>Edit <code>src/App.tsx</code> and save to reload!!!</p>
        <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">Learn React today </a>
        <Table columns={columns} data={data} />
      </header>
    </div>
  );
}

export default App;

CodePudding user response:

You have

<Table columns={columns} data={data} />

so inside Table the columns and data are part of the first argument, the props object.

function Table({ columns, data }: any) : any

But you should really type your identifiers properly - using any completely defeats the purpose of using TypeScript. Proper typing will let you catch these sorts of problems earlier, during compilation.

type Column = { Header: string, accessor: string };
type Data = { col1: string, col2: string };
function Table({
  columns,
  data,
}: {
  columns: Array<Column>,
  data: Array<Data>
}) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({ columns, data });
  // etc

(You don't need to note the return type when TypeScript can infer it automatically - omitting an explicit type when TS can infer it is much preferable to setting it to any)

CodePudding user response:

Your Table function should be

function Table({columns: any, data: any}) : any

instead of

function Table(columns: any, data: any) : any

Because you are passing columns and data as props from here

<Table columns={columns} data={data} />
  • Related