如何在React中每X秒更改一次背景图像?

4

最终编辑:

请看以下可行代码:

import React, { Component } from 'react';


var images = [
  "https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx",
  "https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_March_2010-1.jpg"
]


class App extends Component {

  constructor(props) {
    super(props);
    this.state = { imgPath: "url(" + images[1] + ")" };
  }

  componentDidMount() {
    this.interval = setInterval(() => {
      this.setState({ imgPath: "url(" + images[0] + ")" })
    }, 1000);
  }

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

  render() {
    return (
      <div className="App">
        <div className='dynamicImage' style={{ backgroundImage: this.state.imgPath }} >
          {console.log(this.state.imgPath)}
        </div>
      </div >
    );
  }
}


原始线程:

我正在尝试使用setInterval()每X秒动态更改图片。

我只是不明白setInterval应该放在代码的哪里,或者它的输出应该是什么。

我的当前代码是:

import React, { Component } from 'react';

// Paths to my images
var images = [
  "https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx",
  "https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_March_2010-1.jpg"
]

var imgPath = "url(" + images[1] + ")" // Set original value of path

function f1() {
  imgPath = "url(" + images[0] + ")" // Change path when called ?
}

class App extends Component {
  render() {

    setInterval(f1, 500); // Run f1 every 500ms ?

    return (
      <div className="App">
        <div className='dynamicImage' style={{ backgroundImage: imgPath }} > // Change background image to one specified by imgPath
        </div>
      </div >
    );
  }
}

export default App;

当前代码输出第一个imgPath的URL,但无法将其更新为函数f1中指定的URL。据我所知,函数f1似乎已运行,因为删除它或设置未定义变量会返回错误。我只是不能让它改变imgPath。
你有任何想法吗?或者如何改进我的代码?
干杯
编辑:已注释的代码+删除了不必要的行
6个回答

3
我建议把你的所有变量移到你的组件中,并像Akash Salunkhe建议的那样,使用componentDidMount设置setInterval。不要忘记在组件卸载时清除时间间隔。

这个答案也适用于使用任意数量的图像。

class App extends React.Component {
    constructor(props) {
      super(props);

      const images = [
        "https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx",
        "https://www.petfinder.com/wp-content/uploads/2013/09/cat-black-superstitious-fcs-cat-myths-162286659.jpg",
        "https://upload.wikimedia.org/wikipedia/commons/4/4d/Cat_March_2010-1.jpg"
      ];

      this.state = {
        images,
        currentImg: 0
      }
    }

    componentDidMount() {
      this.interval = setInterval(() => this.changeBackgroundImage(), 1000);
    }

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

    changeBackgroundImage() {
      let newCurrentImg = 0;
      const {images, currentImg} = this.state;
      const noOfImages = images.length;

      if (currentImg !== noOfImages - 1) {
        newCurrentImg = currentImg + 1;
      }

      this.setState({currentImg: newCurrentImg});
    }

    render() {
      const {images, currentImg} = this.state;
      const urlString = `url('${images[currentImg]}')`;

      return (
        <div className="App">
          <div className='dynamicImage' style={{backgroundImage: urlString}} >
          </div>
        </div >
      );
    }
  }

2
你可能希望使用this.propsthis.state来存储imgPath,否则React不知道你已经改变了什么。"最初的回答"

2
将图片路径放在state中,在componentDidMount中使用setInterval,内部使用setState来更改图片路径。最初的回答。

2
@Anurag是正确的。您需要在componentDidMount中使用setInterval,并确保如果您想要重新渲染render方法,则调用this.setState。当然,这需要将图像路径存储在this.state中。"Original Answer"翻译成"最初的回答"。

1
你需要使用componentDidMount() React生命周期方法来注册你的setInterval函数。
这是一个可行的示例。
import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      images: [
        "https://picsum.photos/200/300/?image=523",
        "https://picsum.photos/200/300/?image=524"
      ],
      selectedImage: "https://picsum.photos/200/300/?image=523"
    };
  }

  componentDidMount() {
    let intervalId = setInterval(() => {
      this.setState(prevState => {
        if (prevState.selectedImage === this.state.images[0]) {
          return {
            selectedImage: this.state.images[1]
          };
        } else {
          return {
            selectedImage: this.state.images[0]
          };
        }
      });
    }, 1000);

    this.setState({
      intervalId
    });
  }

  componentWillUnmount() {
    clearInterval(this.state.intervalId);
  }

  render() {
    return (
      <div className="App">
        <img src={this.state.selectedImage} alt={"images"} />
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);


您可以更改代码,并在此处找到实时演示: https://codesandbox.io/s/0m12qmvprp


1
你可以创建一个类似于这样的无限循环,你可能需要使用图像url数组并编写一些逻辑。但是,正如您所看到的,我已经为函数setImage()创建了一个无限循环:
  constructor(props) {
    super();

    this.state = {
      image1: props.imageUrls[0],
      image2: props.imageUrls[1],
      changeImage: true
    };

    this.setImage();
  }

  setImage() {
    setTimeout(() => {
      this.setState({ changeImage: !this.state.changeImage }, this.setImage());
    }, 3000);
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接