0

I'm witnessing a weird behavior when in styled-components with SSR in remix.run

I have a ProductCard Component that renders a normal product card with styled-components

ProductCard.tsx

import Button from "../Button";

function ProductCard({ product }: props) {
  return (
    <>
      <Wrapper>
        ....
        <ButtonsWrapper>
          <Cart
            onClick={addToCart}
            mode={addedToCart ? "secondary" : "primary"}
            disabled={loading}
            key="cart-button"
          >
            {addedToCart ? "Added!" : "Add to cart"}
            {loading && <LoadingSpinner src="/images/responses/loader.svg" />}
          </Cart>
          <ShareButton mode="secondary" aria-label="share">
            <Icon id="share" />
          </ShareButton>
        </ButtonsWrapper>
      </Wrapper>
    </>
  );
}

const Cart = styled(Button)`
  flex: 1.1;
  display: flex;
  justify-content: center;
  gap: 10px;
`;
const ShareButton = styled(Button)`
  padding: 0.9rem;
`;
const Wrapper = styled.div`
  --border-radius: ${clamp(15, 20)};
  --columnGap: ${clamp(20, 30)};
  display: flex;
  flex-direction: column;
  gap: var(--columnGap);
  justify-content: space-between;
  width: 100%;
  height: 100%;
  margin: auto;
  background-color: var(--azure-15);
  padding: 1.9rem 1.5rem;
  border-radius: var(--border-radius);
  box-shadow: var(--box-shadow-lg);
  border: var(--border-lg);
`;
const ButtonsWrapper = styled.div`
  display: flex;
  justify-content: space-between;
  gap: 0.625rem;
`;
export default ProductCard;

Button.tsx

const Button = styled.button<{ mode: "primary" | "secondary" | "dark" }>`
  display: grid;
  /* justify-content: center; */
  align-items: center;
  text-align: center;
  color: var(--mintCream);
  padding: ${clamp(9, 10)} ${clamp(20, 30)}; // this clamp function just generates the css clamp func with calculating the values with some equations
  box-shadow: var(--box-shadow-md);
  border: var(--border-md);
  border-radius: 12px;
  text-decoration: none;
  cursor: pointer;
  transition: all 500ms ease;
  font-size: ${clamp(13, 16)};
  &:disabled {
    cursor: not-allowed;
    opacity: 0.7;
  }
  @media (hover: hover) and (pointer: fine) {
    &:hover:enabled {
      transform: translateY(-2px);    }
  }
  width: fit-content;
`;

The normal render of this Component is as follows

Product card

But when navigating to another path and returning to it on / , it renders like this

corrupted product card

This problem only happens in production and works fine on local server...

when inspecting elements, I find that the class name of the Cart Component is also injected into the ShareButton Element

I can't find an explanation for this problem and it gets weirder... When I swap the order of the variables Cart and ShareButton or swap them with the Wrapper Element, some other weird behaviors happen like the one below

anothe weird behavior

In this case, the class name of the Cart Component got injected on the parent elemnt of the parent element of the ProductCard Component

I've probably hit on 4 of these rendering issues but all of them share the same problem, the class name of the Cart Components gets injected on a wrong dom element, whether it's a parent or a sibiling

You can view the first weird behaviour here https://store.ieeenu.com You will find the product component on the root path, navigate to some path like categories/circuits-1-ecen101 and return to the root and you will see the issue

also, you can review the second weird behavior in a previous build here https://ieee-nu-store-r243eocii-omarkhled.vercel.app/ I just changed the initialization order of the Cart and ShareButton Components as I said earlier

I don't know whether this problem is from styled-components or from remix (this is the first time for me using remix), it's mentioned here https://github.com/remix-run/remix/issues/1032 that the lack of the babel-plugin-styled-components in remix.run introduces some problems in rehydration but I'm not sure that this is the issue I'm facing...

Thanks for reading this till the end and excuse my English, I'm not a native speaker :"

  • Did you follow the guide for using CSS-in-JS for Remix? https://remix.run/docs/en/v1/guides/styling#css-in-js-libraries It does sound weird that classes are added to the wrong components. It might be a react issue. Are you using correct `key` properties to your components when they are rendered from lists? See for example https://reactjs.org/docs/lists-and-keys.html#keys – hakeri Jan 04 '23 at 10:21

0 Answers0