Skip to content

Commit

Permalink
fix(stack): prevent crashing when there's a lot of children (#6684)
Browse files Browse the repository at this point in the history
Co-authored-by: Segun Adebayo <joseshegs@gmail.com>
  • Loading branch information
anubra266 and segunadebayo committed Sep 14, 2022
1 parent a4df8b7 commit 59391bb
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 30 deletions.
8 changes: 8 additions & 0 deletions .changeset/funny-lies-switch.md
@@ -0,0 +1,8 @@
---
"@chakra-ui/layout": patch
---

Prevent Stack from crashing when there's a lot of children

NB: This does not help improve loading and refresh performance otherwise,
libraries like `react-virtualized` should be used to handle large lists.
61 changes: 36 additions & 25 deletions packages/components/layout/src/stack/stack.tsx
Expand Up @@ -98,32 +98,43 @@ export const Stack = forwardRef<StackProps, "div">((props, ref) => {
const hasDivider = !!divider
const shouldUseChildren = !shouldWrapChildren && !hasDivider

const validChildren = getValidChildren(children)

const clones = shouldUseChildren
? validChildren
: validChildren.map((child, index) => {
// Prefer provided child key, fallback to index
const key = typeof child.key !== "undefined" ? child.key : index
const isLast = index + 1 === validChildren.length
const wrappedChild = <StackItem key={key}>{child}</StackItem>
const _child = shouldWrapChildren ? wrappedChild : child

if (!hasDivider) return _child

const clonedDivider = cloneElement(divider as React.ReactElement<any>, {
__css: dividerStyle,
const clones = useMemo(() => {
const validChildren = getValidChildren(children)
return shouldUseChildren
? validChildren
: validChildren.map((child, index) => {
// Prefer provided child key, fallback to index
const key = typeof child.key !== "undefined" ? child.key : index
const isLast = index + 1 === validChildren.length
const wrappedChild = <StackItem key={key}>{child}</StackItem>
const _child = shouldWrapChildren ? wrappedChild : child

if (!hasDivider) return _child

const clonedDivider = cloneElement(
divider as React.ReactElement<any>,
{
__css: dividerStyle,
},
)

const _divider = isLast ? null : clonedDivider

return (
<Fragment key={key}>
{_child}
{_divider}
</Fragment>
)
})

const _divider = isLast ? null : clonedDivider

return (
<Fragment key={key}>
{_child}
{_divider}
</Fragment>
)
})
}, [
divider,
dividerStyle,
hasDivider,
shouldUseChildren,
shouldWrapChildren,
children,
])

const _className = cx("chakra-stack", className)

Expand Down
14 changes: 9 additions & 5 deletions packages/components/layout/src/wrap.tsx
Expand Up @@ -101,11 +101,15 @@ export const Wrap = forwardRef<WrapProps, "div">(function Wrap(props, ref) {
}
}, [spacing, spacingX, spacingY, justify, align, direction])

const childrenToRender = shouldWrapChildren
? Children.map(children, (child, index) => (
<WrapItem key={index}>{child}</WrapItem>
))
: children
const childrenToRender = useMemo(
() =>
shouldWrapChildren
? Children.map(children, (child, index) => (
<WrapItem key={index}>{child}</WrapItem>
))
: children,
[children, shouldWrapChildren],
)

return (
<chakra.div
Expand Down

1 comment on commit 59391bb

@vercel
Copy link

@vercel vercel bot commented on 59391bb Sep 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.