【问题标题】:Why my divs' background image doesn't display in ReactJS为什么我的 div 的背景图像不显示在 ReactJS 中
【发布时间】:2019-12-13 21:49:34
【问题描述】:

我正在尝试在 ReactJS 中的两个背景图像之间进行一些转换。在这里,我在首先显示 backgroundImage 的阶段被阻止,使用 ReactJS 元素的内联样式属性。

这里有一个演示:https://stackblitz.com/edit/react-evdqgw?file=index.js

这是我的 ReactJS 的 sn-p:

import React, { Component } from 'react';
import { render } from 'react-dom'; 
import './style.css';  


class App extends Component {
  constructor(props){
    super(props);
    this.imageSliderRef=React.createRef()
  }
  state = {
    currentImageIndex: 0,
    imageUrlStock:[
      "https://picsum.photos/640/480?image=1",
      "https://picsum.photos/640/480?image=2",
      "https://picsum.photos/640/480?image=3"
    ],
    currentBackgroundImage:{},
    formerBackgroundImage:{}
  };

  componentDidMount() {
    this.interval = setInterval(() => {
      this.nextSlide(); //this function change the index state. 
      }, 3000);   
    console.log("this.state: ", this.state)

  }

  nextSlide() {
    const lastIndex = this.state.imageUrlStock.length - 1;
    const { currentImageIndex } = this.state;
    const index = (currentImageIndex + 1) % (lastIndex + 1)

    // @See https://css-tricks.com/restart-css-animation/
    const elm = this.imageSliderRef
     /* .querySelector('[class^="pic"],[class*=" pix"]');
    elm.className = `pic${index+1}`
    */
    // const newone = elm.cloneNode(true);
    // elm.parentNode.replaceChild(newone, elm);

    this.setState(currentState => ({
        currentImageIndex: index,
        currentBackgroundImage:currentState.imageUrlStock[index],
        formerBackgroundImage:currentState.imageUrlStock[index-1]
    }));
  }



  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
     console.log(`
        this.state.currentBackgroundImage,
        this.state.formerBackgroundImage`,
        this.state.currentBackgroundImage,
        this.state.formerBackgroundImage
    )
    return (  
      <div ref={this.imageSliderRef} className="imageSlider"
      >
        <img className="current" style={{backgroundImage:`url(${this.state.currentBackgroundImage})`}}/> 
        <div className="former" style={{backgroundImage:`url(${this.state.formerBackgroundImage})`}}/>
      </div> 
    );
  }
}

render(<App />, document.getElementById('root'));

这是我的 css 的 sn-p:

h1, p {
  font-family: Lato;
}
body {
  position: relative;
  width: 640px;
  height: 480px;
}

.imageSlider> {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 640px;
  height: 480px;
}
.current {
  z-index: 2;
  opacity: 0;
  animation: in 3s 0s;
 /* background-image:url("https://picsum.photos/640/480?image=1");*/
}
.former {
  z-index: 1;
  opacity: 1;
} 
#root .pic1.init .former {
  background-image: none;
}

/*
#root .pic1 .current,
#root .pic2 .former {
  background-image: url("https://picsum.photos/640/480?image=1");
}

#root .pic2 .current,
#root .pic3 .former {
  background-image: url("https://picsum.photos/640/480?image=2");
}
#root .pic3 .current,
#root .pic1 .former {
  background-image: url("https://picsum.photos/640/480?image=3");
}
*/

@keyframes in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

【问题讨论】:

  • 这是一个&lt;img/&gt; 标签,所以你应该使用src 属性,而不是给它一个CSS背景图片。 &lt;img className="current" src={this.state.currentBackgroundImage} /&gt; 就是你想要的
  • 抱歉, 元素是我在发布帖子之前的拼写错误,最初它实际上是一个 div 元素,请参阅我的回答以更好地理解我的问题 –

标签: javascript css reactjs


【解决方案1】:

您的&lt;img&gt; 元素(旨在显示前景 图像而不是背景 图像:使用src 属性而不是背景样式)没有高度或宽度所以没有像素可以渲染背景图像。

给出元素尺寸。

【讨论】:

  • height: 100px; width: 100px
  • 我的意思是一些代码示例或其他什么,只是尝试使用src,但仍然不起作用
  • 抱歉, 元素是我在发布帖子之前的拼写错误,最初它实际上是一个 div 元素,请参阅我的回答以更好地理解我的问题
【解决方案2】:

我不确定你到底想做什么,但我认为你的答案可能部分在这里。

请关注我的cmets

编辑:@Webwoman 评论后,这是新的答案

const { Component } = React

class App extends Component {
  state = {
    currentImageIndex: 0,
    imageUrlStock: [
      "https://picsum.photos/640/480?image=1",
      "https://picsum.photos/640/480?image=2",
      "https://picsum.photos/640/480?image=3"
    ]
  };

  getNextImageIndex() {
    const { currentImageIndex, imageUrlStock } = this.state;
    return currentImageIndex === imageUrlStock.length - 1
      ? 0
      : currentImageIndex + 1;
  }

  componentDidMount() {
    this.interval = setInterval(() => {
      const newImageIndex = this.getNextImageIndex();
      // Define which img index should be displayed
      this.setState(currentState => ({
        currentImageIndex: newImageIndex
      }));
    }, 3000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    const { imageUrlStock, currentImageIndex } = this.state;
    return (
      <div className="imageSlider">
        {imageUrlStock.map((imgURL, index) => {
          // This flag indicate if the img should show or not
          // Note that all images are loaded at first render, we only toggle the hide/show class
          // to do the transition
          const shouldShow = currentImageIndex === index;
          return (
            <div
              key={imgURL}
              className={`current ${shouldShow ? "show" : "hide"}`}
              // the image URL of a img tag should always be in src, not in the inline style
              style={{backgroundImage:`url(${imageUrlStock[index]})`}}
            />
          );
        })}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
.imageSlider > div {
  /* the "div" tag was missing after the "<" */ 
  position: absolute;
  top: 0;
  left: 0;
  width: 640px;
  height: 480px;
}

.current {
  transition: opacity 1s;
}

.current.show {
  opacity: 1;
}

.current.hide {
  opacity: 0;
}
<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>

<div id="root"></div>

供您参考:

  
  // You should either be doing this
  constructor(props){
    super(props);
    this.state = {
      name: "John"
    }
  }
  
 // Or this
 state = {
    name: "John"
 }
 
 // But not both like this. It is a bad practice
 constructor(props){
    super(props);
  }
  
 state = {
    name: "John"
 }
 

希望对大家有帮助,祝大家编码愉快!

【讨论】:

  • 抱歉, 元素是我在发布帖子之前的拼写错误,最初它实际上是一个 div 元素,请参阅我的回答以更好地理解我的问题
  • @Webwoman 逻辑是一样的,没关系。这是带有 div 的更新版本。希望对您有所帮助。
【解决方案3】:

我坚持我针对所有给他们维度的孩子,但似乎我必须使用通配符来精确定位,我有效地针对所有孩子。我虽然只有element &gt; 就足够了,实际上你必须做element&gt;* 才能针对所有孩子。

因此更新版本有效

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多