设置复杂的反应内联样式,例如悬停,在反应组件(例如按钮)上处于活动状态

Setting Complex react inline styles such as hover, active on react components such as button

我的按钮在 css 中有以下样式。我也在使用 bootstrap.

.btn-primary {
    background-color: #229ac8;
    background-image: linear-gradient(to bottom, #23a1d1, #1f90bb);
    background-repeat: repeat-x;
    border-color: #1f90bb #1f90bb #145e7a;
    color: #ffffff;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.btn-primary:hover, .btn-primary:active, .btn-primary.active, .btn-primary.disabled, .btn-primary[disabled] {
    background-color: #1f90bb;
    background-position: 0 -15px;
}

我在 React 中定义了一个按钮作为一个组件。

const MyButton = ({children, onClick, classNames, ...rest }) =>
(
    <button
        onClick   = {onClick}
        className = {`${classNames}`}
        {...rest}
    >
        {children}
    </button>
);

基于从服务器获取的一些值,我想更改按钮的完整颜色。

问题一:

如何将按钮的完整样式设置为内联样式?

问题二:

此外,我可以使用一些 scss 功能,例如 react 中的 mixins 来生成动态传递 color 作为变量的按钮样式吗?

问题三:

我应该在 js 中使用内联样式还是 class 使用 css 的名称?

对于像按钮这样的通用组件,我们应该使用全局的 class 可以在所有定义按钮的地方重复使用,还是使用本地内联样式并在所有地方创建内联样式?

就个人而言,我会使用全局 CSS 和 wire it up with Webpack。它会让你的 React 更干净,当然也更模块化,更容易编辑。

据我所知,SCSS 功能无法与您的 React 内联使用。

如果你需要在 React 中设置内联样式,可以这样做;

var buttonStyle = {
    backgroundColor: "#229ac8",
    backgroundImage: "linear-gradient(to bottom, #23a1d1, #1f90bb)",
    backgroundRepeat: "repeat-x",
    borderColor: "#1f90bb #1f90bb #145e7a",
    color: "#ffffff",
    textShadow: "0 -1px 0 rgba(0, 0, 0, 0.25)"
}
<button style={buttonStyle}>Button</button>

您可以在按钮中设置一个具有内联样式的 javascript 对象来动态改变颜色。例如:

const normalButtonStyle = {
  background:'gray',
  color:'black',
  borderColor:'white'
}
const buttonCompleteStyle = {
  background:'red',
  color:'white',
  borderColor:'black'
} // this can be included in from another file as a style object as well

const MyButton = ({children, status, onClick, classNames, ...rest }) =>
(
  <button
    onClick   = {onClick}
    className = {`${classNames}`}
    {...rest}
    style={status === 'complete' ? buttonCompleteStyle : normalButtonStyle}
  >
    {children}
  </button>
);

未测试,但类似的东西。看看Material UI是怎么做到的

CSS 在 JS (具有伪 类 和 MQ 支持)

lots of libs to write CSS with React 支持伪 类 但所有(如果不是全部)都需要您在 JS 中内联或编写 CSS 推荐

CSS 模块 (像往常一样写你的 CSS,但写得更好)

还有 CSS modules which if you are already using Webpack should be simple to set it up,它让你 import/require 你的 CSS 作为一个对象使用它你的组件,就像这样:

import styles from './Button.css'

const MyButton = ({children, onClick, type='primary', ...rest }) =>
(
    <button
        onClick   = {onClick}
        className = {styles.primary}
        {...rest}
    >
        {children}
    </button>
);

解耦你的组件

我还要补充一点,您不应将 类 传递给 <Button /> 并处理组件本身内部的条件。例如 使用 classnames lib 你可以做如下的事情。

import classnames from 'classnames'

const MyButton = ({children, onClick, type='primary', ...rest }) =>
(
    <button
        onClick   = {onClick}
        {/* 
          depends on the type prop, you will get the relevent button 
          so no need for consumers to care about the internals of the component
        */}
        className = {classnames('.btn', { [`btn-${type}`]: true })}
        {...rest}
    >
        {children}
    </button>
);

您甚至可以组合 CSS 模块和 classnames 库来创建一些强大的组合。

Question 1:

How can I set the button's complete style as inline style?

来自官方docs:

In React, inline styles are not specified as a string. Instead they are specified with an object whose key is the camelCased version of the style name, and whose value is the style's value, usually a string

给出以下 css

.btn-primary {
    background-color: #229ac8;
    background-image: linear-gradient(to bottom, #23a1d1, #1f90bb);
    background-repeat: repeat-x;
    border-color: #1f90bb #1f90bb #145e7a;
    color: #ffffff;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}

它的内联样式表示是

const MyButton = () =>
(
    <button
        className = { {
            backgroundColor: '#229ac8',
            backgroundImage: 'linear-gradient(to bottom, #23a1d1, #1f90bb)',
            backgroundRepeat: 'repeat-x',
            borderColor: '#1f90bb #1f90bb #145e7a',
            color: '#ffffff',
            textShadow: '0 -1px 0 rgba(0, 0, 0, 0.25)'
        } }
    </button>
);

Question 2

Also, can I use some scss features like mixins in react to generate button styles dynamically passing color as variable ?

React 的内联样式只是css 的抽象。它没有其他花哨的功能。但是由于内联样式只是一个对象,它可以通过模拟 scss mixins 的方式动态生成,当然,您可以使用变量。

A scss mixin 像这样

@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    -ms-border-radius: $radius;
    border-radius: $radius;
}

可以用

之类的东西来完成
const borderRadius = ($radius) => {
    return {
        WebkitBorderRadius: $radius;
        MozBorderRadius: $radius;
        MsBorderRadius: $radius;
        borderRadius: $radius;
    }
}

const MyComponent = () => {
    var inlineStyle = Object.assign({}, borderRadius(10), {
        backgroundColor: 'white'
    })

    return (
        <div style={ inlineStyle }>
            Hello, world!
        </div>
    )
}

Question 3

Should I use inline styles or classnames using css in js?

从这个你无法得到确定的答案。但我建议对泛型使用 className,对特定的使用内联样式。由您决定如何管理代码以满足您的需求。

hover: 使用钩子:

const useFade = () => {
  const [ fade, setFade ] = useState(false);

  const onMouseEnter = () => {
    setFade(true);
  };

  const onMouseLeave = () => {
    setFade(false);
  };

  const fadeStyle = !fade ? {
    opacity: 1, transition: 'all .2s ease-in-out',
  } : {
    opacity: .5, transition: 'all .2s ease-in-out',
  };

  return { fadeStyle, onMouseEnter, onMouseLeave };
};

const ListItem = ({ style }) => {
  const { fadeStyle, ...fadeProps } = useFade();

  return (
    <Paper
      style={{...fadeStyle, ...style}}
      {...fadeProps}
    >
      {...}
    </Paper>
  );
};

您可以对更复杂的场景使用相同的技术。