Search code examples
javascriptcssreactjsstyled-componentsemotion

Using Emotion, new <style> is getting outputted in the <head> every time component's style is dynamically updated


I noticed that new Emotion 's are getting outputted in the every time I update my style dynamically.

Follow an example in which every time DynamicStyleContainer is clicked, a new is created in the head.

import { css } from "@emotion/core";
import styled from "@emotion/styled";

import React from "react";
import _ from "lodash";

const app = css`
  width: 1000px;
  background-color: pink;
  height: 100px;
`;

const dynamicStyle = (props) => ({
  width: props.appDimensions + "px",
});

const DynamicStyleContainer = styled.div`
  ${dynamicStyle};
`;

export default function App() {
  const [appDimensions, setAppDimensions] = React.useState(1);

  const increase = () => {
    setAppDimensions(appDimensions + 1);
  };

  return (
    <DynamicStyleContainer appDimensions={appDimensions}>
      <div id="app" css={app} onClick={increase}></div>
    </DynamicStyleContainer>
  );
}

Inspecting the head element:

enter image description here

I read the documentation and some examples and all seem to do something like this. Is this a normal behavior?


Solution

  • It is expected behavior, CSS-in-JS (like emotion), generates className on every unique style.

    By frequently using a dynamic value like in your case, you will overflow your memory with such styles.

    Instead, use style or css prop.

    <DynamicStyleContainer style={{ width: app.Dimensions }}>
      <div id="app" css={app} onClick={increase}></div>
    </DynamicStyleContainer>;
    

    In styled-components you get a warning for it, don't know about warning in emotion but the fix is the same.

    Over 200 classes were generated for component Component. Consider using style property for frequently changed styles.