Our blazing fast Grid component built with pure JavaScript


Post by saki »

The error message seems to be just a tip of the iceberg so we need a test case.

a) The sync between React and Bryntum was lost. Since I am using column renderers with JSX, the JSX was never re-rendered. I tried to reuse a method from the "WrapperHelper" in the source code for Bryntum to force a re-render of the column renderers, but it didn't work well with my functional component.

This may mean there's a bug somewhere, again, we need a test case to investigate.


Post by Yamo1993 »

saki wrote: Wed Jul 21, 2021 11:06 am

The error message seems to be just a tip of the iceberg so we need a test case.

a) The sync between React and Bryntum was lost. Since I am using column renderers with JSX, the JSX was never re-rendered. I tried to reuse a method from the "WrapperHelper" in the source code for Bryntum to force a re-render of the column renderers, but it didn't work well with my functional component.

This may mean there's a bug somewhere, again, we need a test case to investigate.

Here is a test case (in TypeScript):

import React, { ReactElement, useState } from 'react';
import { BryntumGrid } from '@bryntum/grid-react';
        
const mainTree = [ { id: 1, username: 'User 1', children: [ { id: 11, username: 'User 11', children: [ { id: 111, username: 'User 111', }, ], }, ], }, ]; const subTree = [ { id: 11, username: 'User 11', children: [ { id: 111, username: 'User 111', }, ], }, ]; const Prototyping = (): ReactElement => { const [users, setUsers] = useState<any[]>(mainTree); function switchToMainTree (): void { setUsers(mainTree); } function switchToSubTree (): void { setUsers(subTree); } const columns = [ { text: 'Id', field: 'id', type: 'tree', flex: 1, }, { text: 'Username', field: 'username', flex: 1, }, ]; return ( <> <button onClick={switchToMainTree}>Switch to main tree</button> <button onClick={switchToSubTree}>Switch to sub tree</button> <BryntumGrid treeFeature columns={columns} data={users} autoHeight /> </> ); }; export default Prototyping;

To reproduce:

  1. Click on "Switch to sub tree".
  2. Click on "Switch to main tree". Notice the error.

Post by saki »

In React, we set syncDataOnLoad:true in the wrapper and that does not play well with tree stores. We have the issue here: https://github.com/bryntum/support/issues/2944

I have configured the grid as follows and it worked for me. Just replace App.js of the grid react basic demo with:

import React, { useState } from 'react';
import { BryntumGrid } from '@bryntum/grid-react';

const mainTree = [
    {
        id: 1,
        username: 'User 1',
        children: [
            {
                id: 11,
                username: 'User 11',
                children: [
                    {
                        id: 111,
                        username: 'User 111'
                    }
                ]
            }
        ]
    }
];

const subTree = [
    {
        id: 11,
        username: 'User 11',
        children: [
            {
                id: 111,
                username: 'User 111'
            }
        ]
    }
];

const App = () => {
    const [users, setUsers] = useState(mainTree);

    function switchToMainTree() {
        setUsers(mainTree);
    }

    function switchToSubTree() {
        setUsers(subTree);
    }

    const columns = [
        {
            text: 'Id',
            field: 'id',
            type: 'tree',
            flex: 1
        },
        {
            text: 'Username',
            field: 'username',
            flex: 1
        }
    ];

    return (
        <>
            <button onClick={switchToMainTree}>Switch to main tree</button>
            <button onClick={switchToSubTree}>Switch to sub tree</button>
            <BryntumGrid
                treeFeature
                columns={columns}
                data={users}
                autoHeight
                store={{ syncDataOnLoad: false }}
            />
        </>
    );
};

export default App;

Post by Yamo1993 »

Thanks, saki.

Your solution solved the actual error, but it doesn't fix the column renderer issue. The column still doesn't re-render. Here is another test case which proves this:

TypeScript:

import React, { ReactElement, useState } from 'react';
import { BryntumGrid } from '@bryntum/grid-react';

const flatData = [
    {
        id: 1,
        username: 'User 1',
        isAdmin: false,
    },
    {
        id: 2,
        username: 'User 2',
        isAdmin: false,
    },
    {
        id: 3,
        username: 'User 3',
        isAdmin: false,
    },
    {
        id: 4,
        username: 'User 4',
        isAdmin: false,
    },
];

const Prototyping = (): ReactElement => {
    const [users, setUsers] = useState<any[]>(flatData);

function toggleAdmin (record: any): void {
    setUsers((oldUsers) => {
        const clonedUsers = [...oldUsers];
        const userRecordIndex = oldUsers.findIndex(user => user.id === record.data.id);
        const userObj = {
            ...oldUsers[userRecordIndex],
            isAdmin: !oldUsers[userRecordIndex].isAdmin,
        };
        clonedUsers.splice(userRecordIndex, 1, userObj);
        return clonedUsers;
    });
}

const columns = [
    {
        text: 'Id',
        field: 'id',
        flex: 1,
    },
    {
        text: 'Username',
        field: 'username',
        flex: 1,
    },
    {
        text: 'Is admin',
        field: 'isAdmin',
        flex: 1,
        renderer: (({ record }): ReactElement => {
            return (
                <span onClick={(): void => toggleAdmin(record)}>{record.isAdmin ? 'Yes' : 'No'}</span>
            );
        }),
    },
];

const syncDataOnLoad = true;
return (
    <>
    <h2>syncDataOnLoad: {syncDataOnLoad ? 'true' : 'false'}</h2>
    <BryntumGrid
    columns={columns}
    data={users}
    autoHeight
    store={{ syncDataOnLoad }}
    />
    </>
);
};

export default Prototyping;

To reproduce:

  1. In the column "Is admin", click on the text in any cell (Yes/No) and notice that the column re-renders as expected, since syncDataOnLoad is set to true.
  2. Switch the variable syncDataOnLoad to false and reload the page. Notice that the column doesn't re-render anymore.

Post by saki »

Yes, we are aware of the problem and the problem will be solved as a part of the above ticket. I will add the link to your post to the ticket so that it will be tested against your showcase. Until then I'd recommend to use non-React renderer if possible.


Post by Yamo1993 »

Using a non-React renderer is not possible. We can't throw away our JSX logic just because your grid doesn't support it.


Post by alex.l »

Hi Yamo1993,

Sure, there is no need. It was recommended just as a temporary workaround solution. We will fix it the scope of the ticket provided above.

All the best,
Alex

All the best,
Alex


Post Reply