Ag-grid plain JS cell renderer in React

nig*_*nge 6 javascript reactjs ag-grid

I am using ag-grid in a React application. We have pretty heavy duty tables with custom cells. There are performance issues when using custom cell renderers built as React components, which is the most intuitive discourse.

The ag-grid docs state that this is probably not a good idea:

Do NOT use a framework (eg Angular or React) for the cell renderers. The grid rendering is highly customised and plain JavaScript cell renderers will work faster than framework equivalents.

But it also indicates that plain JS can be used in conjunction with frameworks like React:

It is still fine to use the framework version of ag-Grid (eg for setting ag-Grid properties etc) however because there are so many cells getting created and destroyed, the additional layer the frameworks add do not help performance and should be provided if you are having performance concerns.

Am I misinterpreting this? This seems to me that I can use just a plain JS class as a cell renderer (somehow, maybe they'll handle the integration with React?)

So I took their example code and converted it to a class instead of a function to conform to their typescript definitions:

// function to act as a class
class MyCellRenderer {
    eGui: any;
    eButton: any;
    eValue: any;
    eventListener: any;

    init(params: any) {
        // create the cell
        this.eGui = document.createElement('div');
        this.eGui.innerHTML = 
            '<span class="my-css-class"><button class="btn-simple">Push Me</button><span class="my-value"></span></span>';

        // get references to the elements we want
        this.eButton = this.eGui.querySelector('.btn-simple');
        this.eValue = this.eGui.querySelector('.my-value');

        // set value into cell
        this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value;

        // add event listener to button
        this.eventListener = function() {
            // tslint:disable-next-line
            console.log('button was clicked!!');
        };
        this.eButton.addEventListener('click', this.eventListener);
    }

    // gets called once when grid ready to insert the element
    getGui() {
        return this.eGui;
    }

    // gets called whenever the user gets the cell to refresh
    refresh(params: any) {
        // set value into cell again
        this.eValue.innerHTML = params.valueFormatted ? params.valueFormatted : params.value;
        // return true to tell the grid we refreshed successfully
        return true;
    }

    // gets called when the cell is removed from the grid
    destroy() {
        // do cleanup, remove event listener from button
        this.eButton.removeEventListener('click', this.eventListener);
    }
}

// gets called once before the renderer is used

export default MyCellRenderer;
Run Code Online (Sandbox Code Playgroud)

This builds just fine. Now when I pull up my table in the app, I get the somewhat predictable error:

MyCellRenderer(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

So it was expecting a React component exclusively? It appears that I need to provide the rendering operation anyway.

Does anyone know what's going on here/how to resolve this issue? Am I misinterpreting the documentation?

Thanks!

p.s. ag-grid is awesome!

God*_*ker 2

刚刚弄清楚如何去做。您可以将两组“网格组件”属性提供给渲染器和编辑器的网格实例。

frameworkComponents属性包含将使用您正在使用的框架(例如 React 或 Angular)呈现的属性。

components属性包含将使用直接 JS 渲染的属性。

您可以根据需要混合这些,例如,假设您有一些使用此模式导出的渲染器:

export const XRenderer = {
  id: 'someId',
  renderer: function() ... // or class, or whatever
}
Run Code Online (Sandbox Code Playgroud)
// React components
const frameworkComponents = {
  [CheckboxRenderer.id]: CheckboxRenderer.renderer,
  [SelectRenderer.id]: SelectRenderer.renderer
};

// JavaScript components
const components = {
  [RateRenderer.id]: RateRenderer.renderer
};

<Grid
  columnDefs={columnDefinitions}
  theme={theme}
  rowData={rows}

  frameworkComponents={gridComponents} // React components
  components={components} // JavaScript components

  onGridReady={this.onGridReady}          
  context={this.gridContext}
  gridOptions={this.mainGridOptions}
  ...
/>

Run Code Online (Sandbox Code Playgroud)

有关如何执行此操作的信息实际上在文档中,但不在特别有用的地方:https ://www.ag-grid.com/javascript-grid-components/#mixing-javascript-and-framework