primereact icon indicating copy to clipboard operation
primereact copied to clipboard

Datatable: onRowSelect and onRowUnselect callbacks inconsistent when clicking checkbox in DataTable (v10.9.5)

Open JHerasP opened this issue 8 months ago • 2 comments

Describe the bug

After upgrading PrimeReact from version 8.7.3 to 10.9.5, I encountered a bug with the onRowSelect and onRowUnselect properties on the DataTable.

When testing the new version, existing code began to fail when the selection callbacks were triggered via checkbox clicks. However, the same code works correctly when selecting rows by clicking directly on the row itself.

After some investigation, it seems that the callback reference passed as a prop to the DataTable is inconsistent. Specifically:

  • When clicking on a row, the callback reference is correctly updated and invoked as expected.
  • When clicking on a checkbox, the callback seems to retain the initial reference and does not reflect updates.

This inconsistency causes unexpected behavior and breaks previously working code.

Doing more testing, I realized that when passing the prop onSelectionChange and selection, the functionality of both previous props seems to work as intended.

Code
 import { useState } from 'react';

import { Column } from 'primereact/column'; import { DataTable } from 'primereact/datatable';

import 'primereact/resources/themes/lara-light-indigo/theme.css'; //theme import 'primeicons/primeicons.css'; //icons import 'primeflex/primeflex.css'; // flex import './App.css';

const value = [ { key: '0', data: { id: 'Click me', }, }, { key: '1', data: { id: 'Click me', }, }, ];

function App() { const [counter, setCounter] = useState(0); console.log('counter', counter);

return (

Click a row to increase the number

Number of clicks: {counter} <DataTable value={value} onRowSelect={() => { setCounter(counter + 1); }} > <Column selectionMode="multiple" /> <Column field="data.id" header="wadwa" /> </DataTable>

Click the checkbox to see the error

); }

export default App;

Reproducer

https://stackblitz.com/edit/vitejs-vite-aotetcgn?file=src%2FApp.tsx

System Information

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 20.19.1 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.8.2 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    primereact: 10.9.5 => 10.9.5

Steps to reproduce the behavior

  1. Click anywhere on a row in the DataTable.
  2. Observe that the counter updates correctly with a new value.
  3. Now click the checkbox of any row instead.
  4. The counter resets to its initial value, instead of updating as expected.

Expected behavior

When pressing the checkbox, the invoked callback function should use the updated reference, not the initial one. In the demo, the counter should increment correctly in both cases — clicking the row or the checkbox.

JHerasP avatar Jun 20 '25 09:06 JHerasP

Thank you for the detailed description, it makes the debugging easier and faster.

Replacing the following line setCounter(counter + 1); By setCounter(prev => prev + 1);

Should fix the problem. Let us know if it does :)

acc-cassio avatar Jun 20 '25 13:06 acc-cassio

Thank you for the detailed description, it makes the debugging easier and faster.

Replacing the following line setCounter(counter + 1); By setCounter(prev => prev + 1);

Should fix the problem. Let us know if it does :)

Thank you for your quick response. Yes, your solution does indeed fix the issue presented in the demo.

However, that solution cannot be applied to many other situations. Since the reference to the function passed as a prop to the table is not properly updated, any other value captured in the function's scope will remain static, therefore, holding the initial values passed to the function.

For a practical case, check the following stackblitz

JHerasP avatar Jun 20 '25 17:06 JHerasP

Your new use case can be solved by embedding the counter into the row data as in: https://stackblitz.com/edit/vitejs-vite-g7ie3cac?file=src%2FApp.tsx

It should be solvable as well by setting the new parameter "cellMemo" from v10.9.6 to false. As of right now this parameter does not affect the checkbox cells though, only the table body cells. I will create PR to fix that. Be advised though that using this future option will result in performance issues for large datasets.

acc-cassio avatar Jun 22 '25 11:06 acc-cassio