From 84adab08bd7602b4851f3cc0a1bc5612ff01ef31 Mon Sep 17 00:00:00 2001 From: Julien Deniau Date: Sun, 14 Apr 2024 01:42:26 +0200 Subject: [PATCH] avoid useless re-rendering --- src/contexts/PendingEditContext.tsx | 27 ++++++++++++++++++----- src/renderer/component/Cell.tsx | 13 ++++++----- src/renderer/component/ForeignKeyLink.tsx | 5 +++-- src/renderer/component/TableGrid.tsx | 18 +++++++++------ 4 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/contexts/PendingEditContext.tsx b/src/contexts/PendingEditContext.tsx index 3e5cb4f..7a66c71 100644 --- a/src/contexts/PendingEditContext.tsx +++ b/src/contexts/PendingEditContext.tsx @@ -4,6 +4,7 @@ import { useCallback, useContext, useMemo, + useReducer, useState, } from 'react'; import { Button } from 'antd'; @@ -28,33 +29,47 @@ type PendingEditContextType = { addPendingEdit: (edit: Omit) => void; }; const PendingEditContext = createContext(null); + +type State = Array; + +type Action = { type: 'add'; edit: PendingEdit }; + +function reducer(state: State, action: Action): State { + switch (action.type) { + case 'add': + return [...state, action.edit]; + default: + return state; + } +} + export function PendingEditContextProvider({ children, }: { children: ReactNode; }) { const { currentConnectionSlug } = useConnectionContext(); - const [pendingEdits, setPendingEdits] = useState>([]); + const [pendingEdits, dispatch] = useReducer(reducer, []); const addPendingEdit = useCallback( (edit: Omit) => { invariant(currentConnectionSlug, 'Current connection slug should be set'); - setPendingEdits((prev) => [ - ...prev, - { + dispatch({ + type: 'add', + edit: { state: PendingEditState.Pending, connectionSlug: currentConnectionSlug, ...edit, }, - ]); + }); }, [currentConnectionSlug] ); const value = useMemo( () => ({ pendingEdits, addPendingEdit }), - [pendingEdits, addPendingEdit] + [addPendingEdit, pendingEdits] ); return ( diff --git a/src/renderer/component/Cell.tsx b/src/renderer/component/Cell.tsx index a730706..15b7e44 100644 --- a/src/renderer/component/Cell.tsx +++ b/src/renderer/component/Cell.tsx @@ -1,4 +1,4 @@ -import { ReactNode } from 'react'; +import { ReactNode, memo } from 'react'; import { Flex } from 'antd'; import { Types } from 'mysql'; // immporting from mysql2 will import the commonjs package and will fail import { styled } from 'styled-components'; @@ -65,7 +65,10 @@ function EnumCell({ value }: { value: string }) { return {value}; } -function TableCellFactory({ type, value }: TableCellFactoryProps) { +const TableCellFactory = memo(function TableCellFactory({ + type, + value, +}: TableCellFactoryProps) { if (value === null || typeof value === 'undefined') { return ; } @@ -121,9 +124,9 @@ function TableCellFactory({ type, value }: TableCellFactoryProps) { default: throw new Error(`Type ${type} is not managed for now`); } -} +}); -export default function TableCellFactoryContainer({ +export default memo(function TableCellFactoryContainer({ link, ...rest }: TableCellFactoryProps & { link?: ReactNode }) { @@ -133,4 +136,4 @@ export default function TableCellFactoryContainer({ {link} ); -} +}); diff --git a/src/renderer/component/ForeignKeyLink.tsx b/src/renderer/component/ForeignKeyLink.tsx index 74ae28b..7ac5e26 100644 --- a/src/renderer/component/ForeignKeyLink.tsx +++ b/src/renderer/component/ForeignKeyLink.tsx @@ -1,3 +1,4 @@ +import { memo } from 'react'; import { Link } from 'react-router-dom'; import { styled } from 'styled-components'; import { useConnectionContext } from '../../contexts/ConnectionContext'; @@ -20,7 +21,7 @@ const StyledLink = styled(Link)` } `; -export default function ForeignKeyLink({ +export default memo(function ForeignKeyLink({ tableName, columnName, value, @@ -41,4 +42,4 @@ export default function ForeignKeyLink({ )}`; return ↗️; -} +}); diff --git a/src/renderer/component/TableGrid.tsx b/src/renderer/component/TableGrid.tsx index 0508b44..5c7f666 100644 --- a/src/renderer/component/TableGrid.tsx +++ b/src/renderer/component/TableGrid.tsx @@ -4,6 +4,7 @@ import { ReactElement, ReactNode, useEffect, + useMemo, useRef, useState, } from 'react'; @@ -118,13 +119,16 @@ function CellWithPendingValue({ - } + link={useMemo( + () => ( + + ), + [field.table, field.name, futureValue] + )} /> );