如何在 React 中动态设置 CSS 属性(背景颜色)?

我有一个基于一组具有其特征的对象的幻灯片,其中一个是当前幻灯片的 background-color 。我有一个名为 bg 的属性来存储它。这是我用来设置每个背景颜色的方法,它会更改为每个图像,但是我使用 inline style 来做到这一点。

我想知道是否有办法在不使用这种内联样式的情况下做到这一点?

这是我的代码示例:

import React from 'react'
import { Fragment } from 'react'

import classes from './MainPageHeader.module.css'

const MainPageHeader = props => {

    let [minorSlideImg, setMinorSlideImg] = React.useState(0)

    let minorSlides = [
        {
            img: require('../../../assets/images/Header/MinorSlider/imgSolo1-mainpage.png'),
            alt: 'Produto 1',
            linkText: ['PRODUTO 5', '$ 19.99'],
            productId: 5,
            bg: 'rgb(151, 105, 105)'
        },
        {
            img: require('../../../assets/images/Header/MinorSlider/imgSolo2-mainpage.png'),
            alt: 'Produto 2',
            linkText: ['PRODUTO 13', '$ 199.99'],
            productId: 13,
            bg: '#fad3e0'
        },
        {
            img: require('../../../assets/images/Header/MinorSlider/imgSolo3-mainpage.png'),
            alt: 'Produto 3',
            linkText: ['PRODUTO 10', '$ 499.99'],
            productId: 10,
            bg: '#ccc'
        },
        {
            img: require('../../../assets/images/Header/MinorSlider/imgSolo4-mainpage.png'),
            alt: 'Produto 4',
            linkText: ['PRODUTO 11', '$ 999.99'],
            productId: 11,
            bg: 'rgb(238, 225, 183)'
        },
    ]

    const passSlideHandler = () => {
        if (minorSlideImg < minorSlides.length - 1) {
            setMinorSlideImg(minorSlideImg + 1)
        } else {
            setMinorSlideImg(0)
        }
    }   

    React.useEffect(() => {
        const interval = setTimeout(() => {
            passSlideHandler()
        }, 5000);
        return () => clearTimeout(interval);
    });    

    return (
        <Fragment>
            <div 
                className={classes.MinorSlider_subContainer} 
                style={{backgroundColor: minorSlides[minorSlideImg].bg}} // <= This is what I'd like to remove
            >
                <img 
                    src={minorSlides[minorSlideImg].img}
                    alt={"img-1"} 
                />
            </div>
        </Fragment>
    )
}

export default MainPageHeader

CSS:

.MinorSlider_subContainer {
    height: 65%;
    width: 50%;
    background-color: #ccc;
}

.MinorSlider_subContainer img {
    max-width: 100%;
}

.MinorSlider_subContainer div {
    position: relative;
    background-color: white;
    width: 100%;
    height: 65px;
}

.MinorSlider_subContainer div > *{
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;

    width: 100%;
    height: 100%;
    padding-left: 25px;
    text-decoration: none;
}

.MinorSlider_subContainer div p {
    margin: 0;
    color: rgb(75, 75, 75);
}

可以看出, minorSlides 的索引每五秒就会改变一次,因此,正在显示的幻灯片也会改变。该索引用于引用当前幻灯片的每个特征。

那么,有没有办法删除这种内联样式并使我的 JSX 更干净?

如果我使用 HTML、CSS 和 JS,我可以使用 JQuery 甚至纯 JS 来做到这一点,但我不知道如何在这里做到这一点。我知道我可以使用循环创建元素,但我想只更改索引而不是整个元素。

这是sildeshow:

enter image description here

stack overflow How to set a css property (background-color) dynamically in React?
原文答案

答案:

作者头像

如果不能为每种颜色创建一个 css 类,另一种选择是添加 style 标记并覆盖 background-color 属性:

const subcontainerBackground = `.${classes.MinorSlider_subContainer} { background-color: ${minorSlides[minorSlideImg].bg}}`

return {(
   <Fragment>
      <style>
        {subcontainerBackground}
      </style>
      <div className={classes.MinorSlider_subContainer} >
         //....
      </div>
    </Fragment>
}

编辑

您也可以使用 Document.createElement() 添加样式标签:

  useEffect(() => {
    const content = `.${classes.MinorSlider_subContainer} { background-color: ${minorSlides[minorSlideImg].bg}}`;
    const style = document.createElement("style");
    style.innerHTML = content;
    document.head.appendChild(style);

    return () => document.head.removeChild(style);
  }, [minorSlideImg]);
作者头像

那么在这种情况下使用内联样式应该没问题。

此外,您可以执行以下操作:

{
  ...
  bgClass: 'red'
}

将该类添加到 div 元素:

<div className={`classes.MinorSlider_subContainer ${minorSlides[minorSlideImg].bgClass}`} />

并在最后设置样式:

.red {
  background: 'red';
}

或者您可以尝试使用参考

const ref = useRef()

useEffect(() => {
  if (ref.current == null) {
    return
  }

  ref.current.style.backgroundColor = minorSlides[minorSlideImg].bg
}, [minorSlideImg, ref])

<div ref={ref} />
作者头像

这是我的解决方案。除了,我在列表中添加颜色并使用 rand 函数。

这是颜色列表

 const color_list = [
    "tomato",
    "blueviolet",
    "cornflowerblue",
    "indianred",
    "MediumAquaMarine",
    "MediumPurple",
    "Rebeccapurple",
    "sandybrown",
    "seagreen",
    "palevioletred",
    "lightsteelblue",
    "Gold",
    "teal",
  ];

我创建一个变量并向其添加随机函数,以选择一堆颜色。

const rando_color = color_list[Math.floor(Math.random() * color_list.length)];

只需在 html div 标签中的 style 选项中传递变量即可动态分配背景颜色

<div
   p={4}
   style={{
   backgroundColor: rando_color, // Added variable here 
   fontFamily: "Oswald",
   border: "solid 2px white",
   }}
   >
<h1>Some Content</h1>
  </div>

为简单起见,只需在标签中直接添加变量,无需任何花括号。您也可以尝试在react状态下使用此变量以获得更好的加载。也添加一个默认道具。