From 18aaf86a421b2a761f120fb9d12b34ea65dc8360 Mon Sep 17 00:00:00 2001 From: lokmeinmatz <matze.kind@web.de> Date: Sun, 13 Jun 2021 20:21:51 +0200 Subject: [PATCH] fixed render performance for SportartenTable --- package.json | 1 + .../admin/sports/SportartenTable.tsx | 194 ++++++++++++------ 2 files changed, 131 insertions(+), 64 deletions(-) diff --git a/package.json b/package.json index 8999f01..cd1fc76 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "@types/react-dom": "^16.9.0", "@types/react-redux": "^7.1.7", "babel-jest": "^26.6.0", + "fast-deep-equal": "^3.1.3", "history": "^5.0.0", "react": "^17.0.2", "react-dnd": "^14.0.2", diff --git a/src/components/admin/sports/SportartenTable.tsx b/src/components/admin/sports/SportartenTable.tsx index c559c96..c8b999a 100644 --- a/src/components/admin/sports/SportartenTable.tsx +++ b/src/components/admin/sports/SportartenTable.tsx @@ -11,26 +11,132 @@ import { import AddIcon from '@material-ui/icons/Add' import { ArrowDownward, ArrowUpward } from '@material-ui/icons' import ClearIcon from '@material-ui/icons/Clear' -import {ICategorie, ISport} from "./sportsMockData"; +import { ICategorie, ISport } from './sportsMockData' +import deepEqual from 'fast-deep-equal' interface SportartenTableProps { categories: ICategorie[] sportarten: ISport[] - activ: boolean, - handlerSport:any, - handlerCategorie:any, + activ: boolean + handlerSport: any + handlerCategorie: any } +interface MemoRowProps { + sport: ISport + listIdx: number + categoryWeightChange: (category: string, weight: number) => void + onToggleActive: () => void + onDelete: () => void +} + +function compareRowProps(old: MemoRowProps, n: MemoRowProps): boolean { + console.log(old.sport, n.sport) + + const sportUnchanged = deepEqual(old.sport, n.sport) + //const callbacksUnchanged = old.categoryWeightChange == n.categoryWeightChange && old.onDelete == n.onDelete && old.onToggleActive == n.onToggleActive + + //console.log('sportUnchanged: ', sportUnchanged, 'callbacksUnchanged: ', callbacksUnchanged); + console.log(sportUnchanged && old.listIdx === n.listIdx) + + return sportUnchanged && old.listIdx === n.listIdx +} + +const MemoRow = React.memo( + ({ + sport, + categoryWeightChange, + onToggleActive, + onDelete + }: MemoRowProps) => { + return ( + <TableRow> + <TableCell> {sport.name}</TableCell> + {Object.keys(sport.categoryWeights).map(function (key, idx) { + // TODO: use diffrent key? + return ( + <TableCell key={key}> + <TextField + id="outlined-basic" + type="number" + variant="outlined" + value={sport.categoryWeights[key]} + onChange={(e) => { + categoryWeightChange( + key, + parseInt(e.currentTarget.value, 10) + ) + }} + /> + </TableCell> + ) + })} + <TableCell /> + <TableCell> + <a href={sport.url} target="_blank"> + {sport.url} + </a> + </TableCell> + <TableCell> + <IconButton> + {sport.active ? ( + <ArrowDownward + onClick={() => { + onToggleActive() + }} + /> + ) : ( + <ArrowUpward + onClick={() => { + onToggleActive() + }} + /> + )} + </IconButton> + </TableCell> + <TableCell> + <IconButton> + <ClearIcon + onClick={() => { + onDelete() + }} + /> + </IconButton> + </TableCell> + </TableRow> + ) + }, + compareRowProps +) + export const SportartenTable: React.FC<SportartenTableProps> = ({ sportarten, categories, activ, handlerSport, - handlerCategorie, - + handlerCategorie +}: SportartenTableProps) => { + const deleteEntry = (idx: number) => { + let copy = [...sportarten] + copy.splice(idx, 1) + handlerSport(copy) + } + const toggleActive = (idx: number) => { + let copy = [...sportarten] + copy[idx].active = !copy[idx].active + handlerSport(copy) + } -}: SportartenTableProps) => { + const changeWeight = (idx: number, category: string, weight: number) => { + let copy = [...sportarten] + copy[idx] = { ...copy[idx] } + copy[idx].categoryWeights = { + ...copy[idx].categoryWeights, + [category]: weight + } + handlerSport(copy) + } return ( <Table> @@ -38,7 +144,11 @@ export const SportartenTable: React.FC<SportartenTableProps> = ({ <TableRow> <TableCell> Sportarten </TableCell> {categories.map((elem) => { - return <TableCell key={elem.categorieId}>{elem.categorie}</TableCell> + return ( + <TableCell key={elem.categorieId}> + {elem.categorie} + </TableCell> + ) })} <TableCell> <IconButton> @@ -51,63 +161,19 @@ export const SportartenTable: React.FC<SportartenTableProps> = ({ </TableRow> </TableHead> <TableBody> - {sportarten.map((elem,itx) => { - if (elem.active!=activ) return + {sportarten.map((elem, itx) => { + if (elem.active !== activ) return null return ( - <TableRow key={elem.name}> - <TableCell> {elem.name}</TableCell> - {Object.keys(elem.categoryWeights).map(function(key, idx) { - // TODO: use diffrent key? - return ( - <TableCell key={key}> - <TextField - id="outlined-basic" - type="number" - variant="outlined" - value={elem.categoryWeights[key]} - onChange={(e)=>{ - let copy = [...sportarten] - copy[itx].categoryWeights[key]=parseInt(e.currentTarget.value,10) - handlerSport(copy) - } - } - /> - </TableCell> - ) - })} - <TableCell /> - <TableCell> - <a href={elem.url} target="_blank"> - {elem.url} - </a> - </TableCell> - <TableCell> - <IconButton> - {activ ? ( - <ArrowDownward onClick={()=>{ - let copy = [...sportarten] - copy[itx].active=false - handlerSport(copy) - }}/> - ) : ( - <ArrowUpward onClick={()=>{ - let copy = [...sportarten] - copy[itx].active=true - handlerSport(copy) - }}/> - )} - </IconButton> - </TableCell> - <TableCell> - <IconButton> - <ClearIcon onClick={()=>{ - let copy = [...sportarten] - copy.splice(itx,1) - handlerSport(copy) - }}/> - </IconButton> - </TableCell> - </TableRow> + <MemoRow + key={elem.name} + sport={elem} + listIdx={itx} + onDelete={() => deleteEntry(itx)} + onToggleActive={() => toggleActive(itx)} + categoryWeightChange={(cat, weight) => + changeWeight(itx, cat, weight) + } + /> ) })} </TableBody> -- GitLab