Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When jsxStyleProps=none, components from styled-system/jsx are recreated on every render #2632

Closed
1 of 3 tasks
Temzasse opened this issue May 28, 2024 · 0 comments · Fixed by #2642
Closed
1 of 3 tasks

Comments

@Temzasse
Copy link

Temzasse commented May 28, 2024

Description

Hi 👋🏻 Thank you for this amazing library!

I noticed a sneaky bug related to the styled-system/jsx components such as Stack where the component gets recreated on every render due to the creation of an inner styled() component.

Below I've copied the generated code for Stack where I've marked the potential cause for this bug:

export const Stack = /* @__PURE__ */ forwardRef(function Stack(props, ref) {
  const [patternProps, restProps] = splitProps(props, ['align', 'justify', 'direction', 'gap']);
  const styleProps = getStackStyle(patternProps);
  const Comp = styled('div', { base: styleProps }); // <-- This creates new component on every render!

  return createElement(Comp, { ref, ...restProps });
});

This is generally a bad practice in React as we should not be creating components within components because it will cause hard to detect issues with state, focus, etc. that can be seen in the provided CodeSandbox repro where the input within Stack loses focus on every keystroke while typing to the input.

Link to Reproduction

https://codesandbox.io/p/sandbox/panda-css-repro-6gq83k

Steps to reproduce

  1. Go to the provided CodeSandbox link
  2. Wait until the dev server starts and the page loads
  3. Try to type something in the input field
  4. See that the input gets blurred on every keystroke

JS Framework

React (TS)

Panda CSS Version

0.39.2

Browser

Google Chrome 124

Operating System

  • macOS
  • Windows
  • Linux

Additional Information

Not sure what is the best way to solve this but I've created a temporary version of Stack myself to get around this issue:

import { CSSProperties, ReactNode, forwardRef } from 'react';
import { SpacingToken, token } from '~styled-system/tokens';

type Props = {
  gap: SpacingToken;
  direction?: CSSProperties['flexDirection'];
  align?: CSSProperties['alignItems'];
  justify?: CSSProperties['justifyContent'];
  children: ReactNode;
  className?: string;
  style?: CSSProperties;
};

export const Stack = forwardRef<HTMLDivElement, Props>(
  ({ children, style, gap, direction, align, justify, ...rest }, ref) => {
    return (
      <div
        {...rest}
        ref={ref}
        style={{
          gap: token.var(`spacing.${gap}`),
          display: 'flex',
          flexDirection: direction,
          alignItems: align,
          justifyContent: justify,
          ...style,
        }}
      >
        {children}
      </div>
    );
  }
);

Stack.displayName = 'Stack';

This version doesn't support responsive props which would be nice to add but I'm not sure how to do that 😅

Temzasse added a commit to TaitoUnited/full-stack-template that referenced this issue May 28, 2024
The generated `Stack` component from Panda CSS has a major
bug in it: chakra-ui/panda#2632

This adds a custom `Stack` component with polymorphism support.
@segunadebayo segunadebayo changed the title Components from styled-system/jsx are recreated on every render [jsxStyleProps=none] Components from styled-system/jsx are recreated on every render May 30, 2024
@segunadebayo segunadebayo changed the title [jsxStyleProps=none] Components from styled-system/jsx are recreated on every render When jsxStyleProps=none, components from styled-system/jsx are recreated on every render May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant