首页 > 解决方案 > 样式化的组件默认道具值没有被拾取

问题描述

样式化组件

const Button = styled.button`
  width: 88px;
  height: 36px;
  background:${(props) => buttonTheme[props.buttonTheme].backgroundValue}; 
  box-shadow:${(props) => buttonTheme[props.buttonTheme].boxShadowValue};
  border:${(props) => buttonTheme[props.buttonTheme].borderValue} ;
  border-radius: 6px;
  margin: 5px 0;

`;

默认值

Button.defaultProps = {
  buttonTheme: "defaultButtonTheme"
};

const buttonTheme = {
  defaultButtonTheme: {
    borderValue: "0",
    boxShadowValue: "0",
    backgroundValue: "0"
  },
  defaultButton: {
    backgroundValue: "#E0E0E0",
    boxShadowValue: "0px 2px 3px rgba(51, 51, 51, 0.2)",
    color: "#3F3F3F"
  },
  hoverFocusType1Button: {
    backgroundValue: "#AEAEAE",
    boxShadowValue: "0px 2px 3px rgba(51, 51, 51, 0.2)",
    color: "#3F3F3F"
  },
  OutlineVariantButton: {
    borderValue: "1px solid #3D5AFE",
    color: "#3D5AFE"
  },
  hoverFocusType2Button: {
    backgroundValue: "rgba(41, 98, 255, 0.1)",
    borderValue: "1px solid #3D5AFE",
    color: "#3D5AFE"
  },
  textVariantButton: {
    color: "#3D5AFE"
  },
  hoverFocusType3Button: {
    backgroundValue: "rgba(41, 98, 255, 0.1)",
    color: "#3D5AFE"
  },
}

假设我返回 JSX

<div>
        <Button buttonTheme="defaultButton">Default</Button>
</div>

我的期望是这个道具中缺少哪些值,它应该从默认值中恢复,但它没有按预期工作。

例如,在上述情况下,我期望

borderValue: "0",

但我仍然看到这个按钮的边框,不知道它从哪里来?

标签: reactjsstyled-components

解决方案


你没有得到你想要的,因为defaultButtonTheme没有在任何时候与其他主题合并。

要完成您想要的,您可以执行以下操作:

1.创建两个对象主题,一个带有默认值,另一个带有主题:

const defaultButtonTheme = {
  borderValue: "0",
  boxShadowValue: "0",
  backgroundValue: "0",
};

const buttonTheme = {
  defaultButton: {
    backgroundValue: "#E0E0E0",
    boxShadowValue: "0px 2px 3px rgba(51, 51, 51, 0.2)",
    color: "#3F3F3F",
  },
  hoverFocusType1Button: {
    backgroundValue: "#AEAEAE",
    boxShadowValue: "0px 2px 3px rgba(51, 51, 51, 0.2)",
    color: "#3F3F3F",
  },
  OutlineVariantButton: {
    borderValue: "1px solid #3D5AFE",
    color: "#3D5AFE",
  },
  hoverFocusType2Button: {
    backgroundValue: "rgba(41, 98, 255, 0.1)",
    borderValue: "1px solid #3D5AFE",
    color: "#3D5AFE",
  },
  textVariantButton: {
    color: "#3D5AFE",
  },
  hoverFocusType3Button: {
    backgroundValue: "rgba(41, 98, 255, 0.1)",
    color: "#3D5AFE",
  },
};

2.将您的样式按钮更改为:

const Button = styled.button`
  width: 88px;
  height: 36px;
  border-radius: 6px;
  margin: 5px 0;

  ${(props) => {
    const defaultThemeConcatenated = Object.assign(
      {},
      defaultButtonTheme,
      buttonTheme[props.buttonTheme]
    );

    return css`
      background: ${defaultThemeConcatenated.backgroundValue};
      box-shadow: ${defaultThemeConcatenated.boxShadowValue};
      border: ${defaultThemeConcatenated.borderValue};
    `;
  }}
`;

现在我们将通知主题与默认主题连接起来,通知主题没有的任何属性都将从默认主题中获取。

正如你所看到的,我正在使用css,所以不要忘记导入它。

import styled, { css } from "styled-components";

在这种情况下,我包括return css明确表示我正在从这部分代码返回一些样式,然后它将我的 vscode 的主题颜色设置为此行。

你可以这样做:

return `
      background: ${defaultThemeConcatenated.backgroundValue};
      box-shadow: ${defaultThemeConcatenated.boxShadowValue};
      border: ${defaultThemeConcatenated.borderValue};
    `;

但在这种情况下,background, box-shadow and border不会设置我喜欢的主题颜色。这更像是一个约定。

这是一个代码片段,用于检查代码是否正常工作。

const defaultButtonTheme = {
  borderValue: "0",
  boxShadowValue: "0",
  backgroundValue: "0",
};

const buttonTheme = {
  defaultButton: {
    backgroundValue: "#E0E0E0",
    boxShadowValue: "0px 2px 3px rgba(51, 51, 51, 0.2)",
    color: "#3F3F3F",
  },
  hoverFocusType1Button: {
    backgroundValue: "#AEAEAE",
    boxShadowValue: "0px 2px 3px rgba(51, 51, 51, 0.2)",
    color: "#3F3F3F",
  },
  OutlineVariantButton: {
    borderValue: "1px solid #3D5AFE",
    color: "#3D5AFE",
  },
  hoverFocusType2Button: {
    backgroundValue: "rgba(41, 98, 255, 0.1)",
    borderValue: "1px solid #3D5AFE",
    color: "#3D5AFE",
  },
  textVariantButton: {
    color: "#3D5AFE",
  },
  hoverFocusType3Button: {
    backgroundValue: "rgba(41, 98, 255, 0.1)",
    color: "#3D5AFE",
  },
};

const Button = window.styled.button`
  width: 88px;
  height: 36px;
  border-radius: 6px;
  margin: 5px 0;

  ${(props) => {
    const defaultThemeConcatenated = Object.assign(
      {},
      defaultButtonTheme,
      buttonTheme[props.buttonTheme]
    );

    return window.styled.css`
      background: ${defaultThemeConcatenated.backgroundValue};
      box-shadow: ${defaultThemeConcatenated.boxShadowValue};
      border: ${defaultThemeConcatenated.borderValue};
    `;
  }}
`;

const App = () => {
  return (
 <div>
  <Button buttonTheme="defaultButton">Default</Button>
  <Button buttonTheme="hoverFocusType1Button">Default</Button>
  <Button buttonTheme="OutlineVariantButton">Default</Button>
  <Button buttonTheme="textVariantButton">Default</Button>
  <Button buttonTheme="hoverFocusType3Button">Default</Button>
 </div>     
  );
};

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
div {
 display: flex;
 flex-direction:column; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-is@17.0.2/umd/react-is.production.min.jss"></script>
<script src="//unpkg.com/styled-components@4.0.1/dist/styled-components.min.js"></script>
<div id="root"></div>


推荐阅读