Search code examples
javascriptreactjsslickgrid

React: SlickGrid requires a valid container, #myGrid does not exist in the DOM


I repeatedly getting this error with lot of attempts to fix that issue. Here I am giving my sample code.

index.js,

const app = (
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
    </Provider>

);
ReactDOM.render(app, document.getElementById("root"));

App.js,

import React, { Component } from 'react';

import SlickGrid1 from "./containers/Grids/SlickGrid/GridExamples/Example1";

class App extends Component {
  render () {


    return (
      <div>
          <div id="myGrid"></div>
          <SlickGrid1 />
      </div>
    );
  }
}

export default App;

Example1.js,

import {Grid, Data} from 'slickgrid-es6';
import data from "../example-data";
const columns = [
  { id: "title", name: "Title", field: "title", maxWidth: 100, minWidth: 80 },
  { id: "duration", name: "Duration", field: "duration", resizable: false },
  { id: "%", name: "% Complete", field: "percentComplete" },
  { id: "start", name: "Start", field: "start" },
  { id: "finish", name: "Finish", field: "finish" },
  { id: "effort-driven", name: "Effort Driven", field: "effortDriven" }
];

const options = {
  enableCellNavigation: true,
  enableColumnReorder: true,
  forceFitColumns: !true,
  frozenColumn: 0,
  frozenRow: 1
};

const dataView = new Data.DataView();
dataView.setItems([ ...data ]); // some data


export default new Grid("#myGrid", dataView, columns, options);

Even though, I defined the '#myGrid' div before the <SlickGrid1 /> component rendering, It always throws the same error. How do I fix this issue?


Solution

  • I think you are misunderstanding what exactly new Grid is creating in your code. You are trying to export it as a React component when in fact it is simply creating a grid based on a existing DOM element. Since you are calling new Grid in your export you are exporting an instance. It will try to create the Grid before your App component's render function is triggered, meaning that there is no valid target for it to bind to. Try exporting a factory function instead, like so:

    Example1.js

    import {Grid, Data} from 'slickgrid-es6';
    import data from "../example-data";
    const columns = [
      { id: "title", name: "Title", field: "title", maxWidth: 100, minWidth: 80 },
      { id: "duration", name: "Duration", field: "duration", resizable: false },
      { id: "%", name: "% Complete", field: "percentComplete" },
      { id: "start", name: "Start", field: "start" },
      { id: "finish", name: "Finish", field: "finish" },
      { id: "effort-driven", name: "Effort Driven", field: "effortDriven" }
    ];
    
    const options = {
      enableCellNavigation: true,
      enableColumnReorder: true,
      forceFitColumns: !true,
      frozenColumn: 0,
      frozenRow: 1
    };
    
    const dataView = new Data.DataView();
    dataView.setItems([ ...data ]); // some data
    
    export default () => new Grid("#myGrid", dataView, columns, options);
    

    Then call this factory function in your componentDidMount hook of your App component:

    App.js

    import React, { Component } from 'react';
    
    import SlickGrid1 from "./containers/Grids/SlickGrid/GridExamples/Example1";
    
    class App extends Component {
      componentDidMount() {
        SlickGrid1();
      }
      render () {
    
    
        return (
          <div>
              <div id="myGrid"></div>
          </div>
        );
      }
    }
    
    export default App;
    

    See this working example (I have omitted the test data).