Skip to content

Commit

Permalink
Optimised rerenders on table/form state update. Fixed rowsCount on ad…
Browse files Browse the repository at this point in the history
…ding new rows.
  • Loading branch information
Kuznietsov committed Oct 9, 2023
1 parent 7b3a4c2 commit d31a824
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 20 deletions.
39 changes: 23 additions & 16 deletions app/src/sandbox/project/ProjectDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ let savedValue: FormState = { items: getDemoTasks() };

export function ProjectDemo() {
const {
lens, value, onValueChange, save, isChanged, revert, undo, canUndo, redo, canRedo,
lens, value, save, isChanged, revert, undo, canUndo, redo, canRedo, setValue,
} = useForm<FormState>({
value: savedValue,
onSave: async (data) => {
Expand All @@ -57,26 +57,33 @@ export function ProjectDemo() {
task.parentId = tempRelativeTask.parentId;
}

task.order = getInsertionOrder(
Object.values(value.items)
.filter((i) => i.parentId === task.parentId)
.map((i) => i.order),
position === 'bottom' || position === 'inside' ? 'after' : 'before', // 'inside' drop should also insert at the top of the list, so it's ok to default to 'before'
tempRelativeTask?.order,
);
setValue((currentValue) => {
task.order = getInsertionOrder(
Object.values(currentValue.items)
.filter((i) => i.parentId === task.parentId)
.map((i) => i.order),
position === 'bottom' || position === 'inside' ? 'after' : 'before', // 'inside' drop should also insert at the top of the list, so it's ok to default to 'before'
tempRelativeTask?.order,
);

return { ...currentValue, items: { ...currentValue.items, [task.id]: task } };
});

onValueChange({ ...value, items: { ...value.items, [task.id]: task } });
if (position === 'inside') {
setTableState({ ...tableState, folded: { ...tableState.folded, [`${task.parentId}`]: false } });
setTableState((currentTableState) => ({
...currentTableState,
folded: { ...currentTableState.folded, [`${task.parentId}`]: false },
}));
}
}, [value, onValueChange, tableState, setTableState]);
}, [setValue, setTableState]);

const deleteTask = useCallback((task: Task) => {
const items = { ...value.items };

delete items[task.id];
onValueChange({ ...value, items });
}, [value, onValueChange]);
setValue((currentValue) => {
const items = { ...currentValue.items };
delete items[task.id];
return { ...currentValue, items };
});
}, [setValue]);

const handleCanAcceptDrop = useCallback((params: AcceptDropParams<Task & { isTask: boolean }, Task>) => {
if (!params.srcData.isTask || params.srcData.id === params.dstData.id) {
Expand Down
6 changes: 6 additions & 0 deletions uui-core/src/data/processing/hooks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,9 @@ ListState<TId, TFilter> & {
*/
loadData?: boolean;
};

export type UseListOptionsProps<TItem, TId, TFilter, TProps extends ListViewProps<TItem, TId, TFilter>> = {
view: IView<TItem, TId, TFilter, TProps>;
listState: DataSourceState<TFilter, TId>;
props: TProps;
};
21 changes: 17 additions & 4 deletions uui-core/src/data/processing/hooks/useList.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import { useEffect, useMemo, useRef } from 'react';
import { useView } from './useView';
import { UnboxListProps, UseListProps } from './types';
import { ListViewProps, UnboxListProps, UseListOptionsProps, UseListProps } from './types';
import { createView, mergePropsWithDefaults } from './helpers';

function useListOptions<TItem, TId, TFilter, TProps extends ListViewProps<TItem, TId, TFilter>>({
view, listState, props,
}: UseListOptionsProps<TItem, TId, TFilter, TProps>) {
const deps: unknown[] = [view, listState];
if (props.type === 'array') {
deps.push(
Array.isArray(props.items)
? props.items.length
: props.items,
);
}

return useMemo(() => view.getListProps(), deps);
}

export function useList<TItem, TId, TFilter>(
{ listState, setListState, loadData = true, ...props }: UseListProps<TItem, TId, TFilter>,
deps: any[],
) {
const prevLoadDataRef = useRef(false);
// const prevListState = usePrevious(listState);

useEffect(() => {
prevLoadDataRef.current = loadData;
Expand All @@ -29,8 +43,7 @@ export function useList<TItem, TId, TFilter>(
}

const rows = view.getVisibleRows();
const listProps = useMemo(() => view.getListProps(), [view, listState]);

const listProps = useListOptions({ view, props, listState });
return {
rows,
listProps,
Expand Down

0 comments on commit d31a824

Please sign in to comment.