【问题标题】:How to set a css property (background-color) dynamically in React?如何在 React 中动态设置 CSS 属性(背景颜色)?
【发布时间】:2021-03-24 09:30:50
【问题描述】:

我有一个基于对象数组及其特征的幻灯片,其中一个是当前幻灯片的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 的索引每 5 秒就会发生一次变化,因此,正在显示的幻灯片也会发生变化。该索引用于引用当前幻灯片的每个特征。

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

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

这里是幻灯片:

【问题讨论】:

  • 您能分享您当前输出的图片或短视频吗?
  • @Rojo 我插入了一个 GIF。我将间隔更改为 1500 以使 GIF 更短。
  • 那么使用inline有什么问题?
  • 没问题。我只想让 JSX 更干净。
  • 如果要移除内联样式,可以为每种颜色创建一个 css 类,而不是设置样式,您可以设置 className 值,还是动态获取此数据?

标签: javascript css reactjs loops jsx


【解决方案1】:

如果您不能为每种颜色创建一个 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]);

【讨论】:

    【解决方案2】:

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

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

    {
      ...
      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} />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-29
      • 1970-01-01
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-25
      相关资源
      最近更新 更多