Posted 13 May 2024, 1:28 pm EST
I am displaying a MultiRow grid that displays 2 rows for each row of data. The first row is to display the data and the second row is to display any messages about the data that were received from the server. Here is the definition:
<MultiRow ref={gridRef} itemsSource={data}>
<MultiRowCellGroup>
<MultiRowCell binding="carNumber" header="Car Number" width={150} isReadOnly={true} />
<MultiRowCell binding="inboundDate" header="Inbound Date" width={150} cellType="Cell">
<MultiRowCellTemplate cellType="CellEdit" template=
{(context: any) => (
<InputDate value={context.value}
valueChanged={(inputDate: any) => context.value = inputDate.value} />
)} />
</MultiRowCell>
<MultiRowCell binding="shopProcessing" header="Shop Processing" width={150} />
<MultiRowCell binding="message" header="Feedback Message" colspan={3} isReadOnly={true} allowSorting={false}>
<MultiRowCellTemplate cellType="Cell" template=
{(context: any) => <MessageCellTemplate context={context} gridRef={gridRef} />} />
</MultiRowCell>
</MultiRowCellGroup>
</MultiRow>
Note the definition of the “Feedback Message” row has a colspan of 3. So for each row of data, the grid will display one row containing the data and a second row displaying a message from the server. However, we only want to show this Feedback Message row IF a message was sent from the server. Otherwise we want to hide it. Here is the MessageCellTemplate code used to show and hide the Feedback Message row:
const MessageCellTemplate: React.FC<{ context: any, gridRef: any }> = ({ context, gridRef }) => {
if (context.item.message) {
// We want to show the "Message" line if a message exists
context.row.height = null;
} else {
// Hide the "Message" line if no message exists
context.row.height = 0
}
return context.item.message
? <span>
{context.item.message}
</span>
: null;
}
The code works on first render of the grid. Our app uses a socket to send and receive updated data from the server. When we get updated data from the server in the socket and modify the data state variable, the grid refreshes. Unfortunately, it also causes the error:
flushSync was called from inside a lifecycle method. React cannot flush when React is already rendering. Consider moving this call to a scheduler task or micro task
The Message rows display correctly, we are just getting the error from the MultiRow grid.
One thing to note: If we comment out the line
context.row.height = 0
then the flushSync error does not happen. I have attached a zip file that contains a simple NestJS server to host the socket and a React app that communicates via the socket.
Steps to replicate the error:
1 - Start Server
2 - Start React app. This should connect to the server socket
3 - Change any data in the grid. Click “Save”
4 - Data will be sent to the server via the socket and then broadcast back down. Open the browser console to observe error.
multirow-grid-demo.zip