4

I am trying to copy this example using react data grid into my Typescript project. I created the following class to match the one provided....

import * as React from "react";
import ReactDataGrid from "react-data-grid";
interface PxGridProps {}
interface PxGridState {}
export default class PxGrid extends React.Component<PxGridProps, PxGridState>{
    private _columns;
    private _rows;
    constructor(props) {
        super(props);
        this.props = props;
        this.createRows();
        this._columns = [
            { key: 'id', name: 'ID' },
            { key: 'title', name: 'Title' },
            { key: 'count', name: 'Count' } ];
        return null;
    }

    createRows() {
        let rows = [];
        for (let i = 1; i < 1000; i++) {
            rows.push({
                id: i,
                title: 'Title ' + i,
                count: i * 1000
            });
        }

        this._rows = rows;
    }

    rowGetter(i) {
        return this._rows[i];
    }

    render() {
        return  (
            <ReactDataGrid
                minHeight={500}
                columns={this._columns}
                rowGetter={this.rowGetter.bind(this)}
                rowsCount={this._rows.length}
                 />
        );
    }
}

But when I try to run it I get

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in. Check the render method of PxGrid.

If I replace out the render to something like this....

render() {
        return  (
            <h1> Thing </h1>
        );
}

It works fine. What am I getting wrong? The error message is not helping at all.

Jackie
  • 21,969
  • 32
  • 147
  • 289

2 Answers2

3

This was an issue importing. Not sure what was causing it but when I have import ReactDataGrid from "react-data-grid"; and debug on

render() {
    return  (
        <ReactDataGrid
            minHeight={500}
            columns={this._columns}
            rowGetter={this.rowGetter.bind(this)}
            rowsCount={this._rows.length}
             />
    );
}

I see ReactDataGrid is undefined. For some reason I needed to change my import to...

import * as ReactDataGrid from "react-data-grid";

And everything started working fine.

Jackie
  • 21,969
  • 32
  • 147
  • 289
  • 1
    When you import with `*` all of the exported functions are imported to the file (which may not be needed in your case). Simple `import ReactDataGrid ...` does not work if there's no default export. So if you want to import only `ReactDataGrid` you can do this by writing `import { ReactDataGrid } from 'react-data-grid'` – Deividas Mar 03 '17 at 19:00
  • I tried that and it did not work. When I did `import { ReactDataGrid } from 'react-data-grid'` it returned undefined but `import * as ReactDataGrid from "react-data-grid";` returned the proper function – Jackie Mar 03 '17 at 19:14
  • 1
    This means that the exported function is named differently (not `ReactDataGrid`). However, since you import all functions (`*`) and create their alias as `ReactDataGrid` it means that there's only one function, so your method is fine. Bear in mind that if more methods are added, this could break your app. You could check the source code to see the name of the component so you could import only that component. Interesting case though! – Deividas Mar 03 '17 at 19:19
  • Yeah I have to dig in a bit, I wonder if it isn't something to do with the fact that I am using webpack and typescript. A person from the team was helping me and his import worked fine the other way in his environment (JS no Webpack), so I wonder if webpack is doing something funky – Jackie Mar 03 '17 at 19:26
0

Don't know much about the typescript, check this working code and do the changes, it should work in your case also:

class Example extends React.Component{
  constructor() {
    super();
    this._columns = [
      { key: 'id', name: 'ID' },
      { key: 'title', name: 'Title' },
      { key: 'count', name: 'Count' } ];
    this._rows = this.createRows();   
  }
  
  createRows() {
    let rows = [];
    for (let i = 1; i < 1000; i++) {
      rows.push({
        id: i,
        title: 'Title ' + i,
        count: i * 1000
      });
    }
    return rows;
  }

  rowGetter(i) {
    return this._rows[i];
  }

  render() {
    return  (
      <ReactDataGrid
        columns={this._columns}
        rowGetter={this.rowGetter.bind(this)}
        rowsCount={this._rows.length}
        minHeight={500} />);
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<script type="text/javascript" src="https://npmcdn.com/react-data-grid/dist/react-data-grid.min.js"></script>

<div id='container'/>
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142