【问题标题】:Making a Responsive Styled Component DRYer制作响应式组件 DRYer
【发布时间】:2020-01-24 10:51:51
【问题描述】:

我有以下代码可以帮助我在Styled Components 中进行响应式设计:

const breakpoints = {
  tablet: "769px",
  desktop: "1024px",
  widescreen: "1216px",
  fullhd: "1408px"
};

const gridCSS = ({ bg, color }) => css`
  background-color: ${bg};
  color: ${color};
`;

const responsiveGrid = (key, prop) =>
  prop &&
  css`
    @media screen and (min-width: ${breakpoints[key]}) {
      color: ${prop.color};
      background-color: ${prop.bg};
    }
  `;

const Grid = styled.div(
  ({ color, bg, desktop, tablet }) => css`
  display: grid;
  justify-content: center;
  align-content: center;
  min-height: 100vh;
  ${responsiveGrid("tablet", tablet)}
  ${responsiveGrid("desktop", desktop)}
  ${gridCSS}
`
);

function App() {
  return (
    <Grid
      color="orange"
      bg="lightgreen"
      tablet={{
        color: "green",
        bg: "orange"
      }}
      desktop={{
        color: "yellow",
        bg: "purple"
      }}
    >
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </Grid>
  );
}

现在这可以按我的意愿工作。文本和背景颜色会根据屏幕大小而变化。

但是,我想指出代码中有一定的重复性:

例如,gridCSS 函数包含与 responsiveGrid 函数完全相同的 css 属性和道具名称。它们都具有colorbackground-color 属性,并且它们都引用了colorbg 属性。

但是,如果我尝试将 gridCSS 注入到 `responsiveGrid 中,它不起作用。 换句话说,这是可行的:

const responsiveGrid = (key, {bg, color}) =>
  (color || bg) &&
  css`
    @media screen and (min-width: ${breakpoints[key]}) {
      color: ${color};
      background-color: ${bg};
    }
  `;

但这确实不起作用

const responsiveGrid = (key, {bg, color}) =>
  (color || bg) &&
  css`
    @media screen and (min-width: ${breakpoints[key]}) {
      ${gridCSS}
    }
  `;

所以,我想知道是否有一种方法可以为 css 属性名称及其相应的 props 提供一个中心位置,而无需编写两次(一次在 gridCSS 函数中,第二次在responsiveGrid 函数中。

注意,我正在寻找的最终结果如下:

function App() {
  return (
    <Grid
      color="orange"
      bg="lightgreen"
      tablet={{
        color: "green",
        bg: "orange"
      }}
      desktop={{
        color: "yellow",
        bg: "purple"
      }}
    >
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
    </Grid>
  );
}

我可以在没有任何媒体查询的情况下设置colorbg 道具,也可以在tabletdesktop 等媒体查询道具中设置same 道具。

有什么想法吗?

谢谢。

附:如果有帮助,这里是上面代码的代码框:https://codesandbox.io/s/vigorous-brook-ughkv?fontsize=14

【问题讨论】:

    标签: javascript reactjs styled-components react-props react-component


    【解决方案1】:

    这是我想出的解决方案:

    const breakpoints = {
      tablet: {
        value: 769,
        unit: "px"
      },
      desktop: {
        value: 1024,
        unit: "px"
      },
      widescreen: {
        value: 1216,
        unit: "px"
      },
      fullhd: {
        value: 1408,
        unit: "px"
      }
    };
    
    const breakpointKeys = Object.keys(breakpoints);
    
    const gridCSS = ({ bg, textColor, ...props }) => {
      let mediaQueryCSS = breakpointKeys.map(key => {
        let mediaQuery = breakpoints[key].value + breakpoints[key].unit;
        let newMQ = mediaQuery - 1
        console.log(newMQ)
    
        return css`
          @media screen and (min-width: ${mediaQuery}) {
            color: ${props[key] && props[key].textColor};
            background-color: ${props[key] && props[key].bg};
          }
        `;
      });
    
      return css`
        background-color: ${bg};
        color: ${textColor};
        ${mediaQueryCSS};
      `;
    };
    
    const Grid = styled.div(
      ({ color, bg, desktop, tablet }) => css`
        display: grid;
        justify-content: center;
        align-content: center;
        min-height: 100vh;
        ${gridCSS}
      `
    );
    
    function App() {
      return (
        <Grid
          textColor="orange"
          bg="lightgreen"
          tablet={{
            textColor: "green",
            bg: "orange"
          }}
          desktop={{
            textColor: "yellow",
            bg: "purple"
          }}
        >
          <div className="App">
            <h1>Hello CodeSandbox</h1>
            <h2>Start editing to see some magic happen!</h2>
          </div>
        </Grid>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 2019-11-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-23
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多