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

Posted

技术标签:

【中文标题】设置复杂的反应内联样式,例如悬停,在反应组件(例如按钮)上处于活动状态【英文标题】:Setting Complex react inline styles such as hover, active on react components such as button 【发布时间】:2016-12-06 13:05:07 【问题描述】:

我的按钮在 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);

.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>
);

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

问题 1:

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

问题 2:

另外,我可以使用react 中的mixinsscss 功能来动态生成按钮样式,并将color 作为变量传递?

问题 3:

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

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

【问题讨论】:

【参考方案1】:

JS 中的 CSS (带有伪类和 MQ 支持)

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

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

还有CSS modules,如果你已经在使用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>
);

解耦你的组件

我还要补充一点,您不应该将类传递给 &lt;Button /&gt; 并处理组件本身内部的条件。例如使用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 lib 来创建一些强大的组合。

【讨论】:

这个语法:-$type 有什么作用? @ahmedelgabri @Tekill 它将 type 属性连接到类名,因此如果您传递 &lt;Button type="primary" /&gt; 等,它将是 .btn-primary... 为什么推荐用 JS 写 CSS? @danielrvt 我不推荐它,因为技术中的一切取决于。我没有看到 vanilla CSS 有什么问题,我也没有看到 CSS-in-JS 有什么问题,两者都是有效的 options 取决于您的需求和您要解决的问题。 感谢您提供的带有 React 库的 CSS 列表【参考方案2】:

就个人而言,我会使用全局 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>

【讨论】:

在css中设置hover等伪类怎么样? 不幸的是,这不是直接可能的。您可以“模拟”悬停动作并通过使用类似“onMouseEnter”/“onMouseLeave”策略的方式以编程方式更改样式。但对我来说似乎有点乱。【参考方案3】:

问题 1:

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

来自官方docs:

在 React 中,内联样式不指定为字符串。相反,它们是用一个对象指定的,其键是样式名称的驼峰式版本,其值是样式的值,通常是一个字符串

给定以下 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>
);

问题 2

另外,我可以在 react 中使用一些 scss 功能(如 mixins)来生成动态将颜色作为变量传递的按钮样式吗?

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

一个像这样的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>
    )

问题 3

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

从这个你无法得到明确的答案。但我建议将 className 用于泛型,将内联样式用于细节。取决于您如何管理代码以满足您的需求。

【讨论】:

【参考方案4】:

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>
  );
;

您可以将相同的技术用于更复杂的场景。

【讨论】:

钩子看起来很有前途,一定会试一试的。 确保 useState 已导入。 import React, useState from "react"; 像魅力一样工作!这个答案被低估了,应该排在首位。【参考方案5】:

您可以在按钮中设置具有内联样式的 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是怎么做到的。

【讨论】:

我最初对悬停状态的 onMouseEnter 说了一些话,但是在考虑更多时,我认为您实际上不需要它,除非您希望在按钮已更改时更改颜色盘旋在上方。如果是这样,它就像添加 onMouseEnter 并使用一些状态来更改您正在使用的样式对象一样简单。

以上是关于设置复杂的反应内联样式,例如悬停,在反应组件(例如按钮)上处于活动状态的主要内容,如果未能解决你的问题,请参考以下文章

反应:内联有条件地将道具传递给组件

如何设置反应选择选项的样式

如何使用下一个 js 设置反应引导轮播的样式?

垂直中心/改变计算高度反应光滑

如何使用道具制作条件并反应动态主题?

具有本机反应的条件内联样式[重复]