Our blazing fast Grid component built with pure JavaScript


Post by Yamo1993 »

I can't use two-way data binding in column renderers. For example, I want to use a dropdown list in a column renderer. I have hooked the dropdown list to a React state. Whenever the state updates, I am getting this error:

"Warning: unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering."

Here is a test case:

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

const sections = [
    { id: 'a', text: 'A' },
    { id: 'b', text: 'B' },
    { id: 'c', text: 'C' },
    { id: 'd', text: 'D' },
];

function rowReducer (state, action) {
    function addRow (state) {
        const row = { id: state.idCounter, section: '', seat: '' };
        state.idCounter++;
        return {
            ...state,
            rows: [...state.rows, row],
        };
    }

function changeSection (state, action) {
    const rowIndex = state.rows.findIndex(r => r.id === action.id);
    const section = sections.find(s => s.id === action.value);
    const row = state.rows[rowIndex];
    const changedRow = {
        ...row,
        section,
    };
    const rows = [...state.rows];
    rows.splice(rowIndex, 1, changedRow);
    return {
        ...state,
        rows,
    };
}

switch (action.type) {
case 'addRow':
    return addRow(state);
case 'changeSection':
    return changeSection(state, action);
default:
    return state;
}
}


const Prototyping = () => {
    const [state, dispatch] = useReducer(rowReducer, { idCounter: 1, rows: [] });

function addRow () {
    dispatch({ type: 'addRow' });
}

function onSectionChange (e, id) {
    dispatch({ type: 'changeSection', value: e.target.value, id });
}

return (
    <>
        <button onClick={addRow}>Add row</button>
        <BryntumGrid
            data={state.rows}
            columns={[
                {
                    field: 'section',
                    text: 'Section',
                    renderer (data) {
                        return (
                            <select value={data.record.section} onChange={e => onSectionChange(e, data.record.section.id)}>
                                {sections.map(s => (
                                    <option key={s.id} value={s.id}>{s.text}</option>
                                ))}
                            </select>
                        );
                    },
                },
                {
                    field: 'seat',
                    text: 'Seat',
                },
            ]}
        />
    </>
);
};

export default Prototyping;

To reproduce:

  1. Click on "Add row".
  2. Change the value in the dropdown list under the column "Section".
  3. Notice the error message.

Post by saki »

Would you please post a complete showcase that we can drop on disk and execute npm i && npm start to run and reproduce it?


Post Reply