Call onSelect when a DataSource item changes
Summary: Currently, we call onSelect in DataTable only when user changes their selection. At that moment, we pass the row data to the `onSelect` callback. However, if later the data changes, but the selection stays the same, we do not call `onSelect` again. As result, any listener to onSelect does not receive the latest data. In this diff, we start calling `onSelect` when the selection does not change, but the underlying data does. Reviewed By: mweststrate Differential Revision: D37520346 fbshipit-source-id: a88d34654e9ad0721caf5918dde49b86ba20fc1f
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1052384154
commit
f8763f95fa
@@ -104,7 +104,8 @@ export function MasterDetail<T extends object>({
|
||||
|
||||
// if a tableManagerRef is provided, we piggy back on that same ref
|
||||
// eslint-disable-next-line
|
||||
const tableManagerRef = tableProps.tableManagerRef ?? createRef<undefined | DataTableManager<T>>();
|
||||
const tableManagerRef =
|
||||
tableProps.tableManagerRef ?? createRef<undefined | DataTableManager<T>>();
|
||||
|
||||
const pausedState = useValue(isPaused, false);
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ import {debounce} from 'lodash';
|
||||
import {useInUnitTest} from '../../utils/useInUnitTest';
|
||||
import {createDataSource} from '../../state/createDataSource';
|
||||
import {HighlightProvider} from '../Highlight';
|
||||
import {useLatestRef} from '../../utils/useLatestRef';
|
||||
|
||||
type DataTableBaseProps<T = any> = {
|
||||
columns: DataTableColumn<T>[];
|
||||
@@ -179,6 +180,26 @@ export function DataTable<T extends object>(
|
||||
|
||||
const {columns, selection, searchValue, sorting} = tableState;
|
||||
|
||||
const latestSelectionRef = useLatestRef(selection);
|
||||
const latestOnSelectRef = useLatestRef(onSelect);
|
||||
useEffect(() => {
|
||||
if (dataSource) {
|
||||
const unsubscribe = dataSource.view.addListener((change) => {
|
||||
if (
|
||||
change.type === 'update' &&
|
||||
latestSelectionRef.current.items.has(change.index)
|
||||
) {
|
||||
latestOnSelectRef.current?.(
|
||||
getSelectedItem(dataSource, latestSelectionRef.current),
|
||||
getSelectedItems(dataSource, latestSelectionRef.current),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return unsubscribe;
|
||||
}
|
||||
}, [dataSource, latestSelectionRef, latestOnSelectRef]);
|
||||
|
||||
const visibleColumns = useMemo(
|
||||
() => columns.filter((column) => column.visible),
|
||||
[columns],
|
||||
|
||||
@@ -737,6 +737,8 @@ test('selection always has the latest state', () => {
|
||||
act(() => {
|
||||
ds.update(2, item3updated);
|
||||
});
|
||||
expect(events.splice(0)).toEqual([[item3updated, [item3updated]]]);
|
||||
|
||||
act(() => {
|
||||
ref.current!.addRangeToSelection(0, 0);
|
||||
});
|
||||
@@ -745,5 +747,16 @@ test('selection always has the latest state', () => {
|
||||
[item1, [item1, item3updated]], // update reflected in callback!
|
||||
]);
|
||||
|
||||
const item1updated = {
|
||||
title: 'item 1 updated',
|
||||
done: false,
|
||||
};
|
||||
act(() => {
|
||||
ds.update(0, item1updated);
|
||||
});
|
||||
expect(events.splice(0)).toEqual([
|
||||
[item1updated, [item1updated, item3updated]], // update reflected in callback!
|
||||
]);
|
||||
|
||||
rendering.unmount();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user