Skip to content

Commit 073f796

Browse files
authored
fix(@rjsf/chakra-ui): performance issues with array fields (rjsf-team#2794)
1 parent 7d22b99 commit 073f796

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

packages/chakra-ui/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useMemo } from "react";
22

33
import { utils } from "@rjsf/core";
44

@@ -62,42 +62,51 @@ const ArrayFieldDescription = ({
6262
};
6363

6464
// Used in the two templates
65-
const DefaultArrayItem = (props: any) => {
65+
const DefaultArrayItem = ({
66+
index, readonly, disabled, children, hasToolbar, hasRemove, hasMoveUp, hasMoveDown, onReorderClick, onDropIndexClick
67+
}: any) => {
68+
69+
const onRemoveClick = useMemo(() => onDropIndexClick(index), [index, onDropIndexClick]);
70+
71+
const onArrowUpClick = useMemo(() => onReorderClick(index, index - 1), [index, onReorderClick]);
72+
73+
const onArrowDownClick = useMemo(() => onReorderClick(index, index + 1), [index, onReorderClick]);
74+
6675
return (
67-
<HStack key={props.key} alignItems={"flex-end"} py={1}>
76+
<HStack alignItems={"flex-end"} py={1}>
6877
<Box w="100%">
69-
{props.children}
78+
{children}
7079
</Box>
7180

72-
{props.hasToolbar && (
81+
{hasToolbar && (
7382
<Box>
7483
<ButtonGroup isAttached mb={1}>
75-
{(props.hasMoveUp || props.hasMoveDown) && (
84+
{(hasMoveUp || hasMoveDown) && (
7685
<IconButton
7786
icon="arrow-up"
7887
tabIndex={-1}
79-
disabled={props.disabled || props.readonly || !props.hasMoveUp}
80-
onClick={props.onReorderClick(props.index, props.index - 1)}
88+
disabled={disabled || readonly || !hasMoveUp}
89+
onClick={onArrowUpClick}
8190
/>
8291
)}
8392

84-
{(props.hasMoveUp || props.hasMoveDown) && (
93+
{(hasMoveUp || hasMoveDown) && (
8594
<IconButton
8695
icon="arrow-down"
8796
tabIndex={-1}
8897
disabled={
89-
props.disabled || props.readonly || !props.hasMoveDown
98+
disabled || readonly || !hasMoveDown
9099
}
91-
onClick={props.onReorderClick(props.index, props.index + 1)}
100+
onClick={onArrowDownClick}
92101
/>
93102
)}
94103

95-
{props.hasRemove && (
104+
{hasRemove && (
96105
<IconButton
97106
icon="remove"
98107
tabIndex={-1}
99-
disabled={props.disabled || props.readonly}
100-
onClick={props.onDropIndexClick(props.index)}
108+
disabled={disabled || readonly}
109+
onClick={onRemoveClick}
101110
/>
102111
)}
103112
</ButtonGroup>
@@ -131,7 +140,10 @@ const DefaultFixedArrayFieldTemplate = (props: ArrayFieldTemplateProps) => (
131140
className="row array-item-list"
132141
key={`array-item-list-${props.idSchema.$id}`}
133142
>
134-
{props.items && props.items.map(DefaultArrayItem)}
143+
{props.items && props.items.map((p) => {
144+
const { key, ...itemProps } = p;
145+
return <DefaultArrayItem key={key} {...itemProps}></DefaultArrayItem>;
146+
})}
135147
</div>
136148

137149
{props.canAdd && (
@@ -168,7 +180,10 @@ const DefaultNormalArrayFieldTemplate = (props: ArrayFieldTemplateProps) => (
168180

169181
<Grid key={`array-item-list-${props.idSchema.$id}`}>
170182
<GridItem>
171-
{props.items.length > 0 && props.items.map(p => DefaultArrayItem(p))}
183+
{props.items.length > 0 && props.items.map((p) => {
184+
const { key, ...itemProps } = p;
185+
return <DefaultArrayItem key={key} {...itemProps}></DefaultArrayItem>;
186+
})}
172187
</GridItem>
173188
{props.canAdd && (
174189
<GridItem justifySelf={"flex-end"}>

packages/chakra-ui/src/IconButton/IconButton.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { memo } from "react";
22
import {
33
IconButton,
44
IconButtonProps as ChakraIconButtonProps,
@@ -26,9 +26,11 @@ type IconButtonProps = Omit<ChakraIconButtonProps, "aria-label" | "icon"> & {
2626
* props used in Template:
2727
* icon, tabIndex, disabled, onClick
2828
*/
29-
const ChakraIconButton = (props: IconButtonProps) => {
29+
const ChakraIconButton = memo((props: IconButtonProps) => {
3030
const { icon, ...otherProps } = props;
3131
return <IconButton {...otherProps} icon={mappings[icon]} aria-label={icon} />;
32-
};
32+
});
33+
34+
ChakraIconButton.displayName = 'ChakraIconButton';
3335

3436
export default ChakraIconButton;

0 commit comments

Comments
 (0)