【问题标题】:Adding setInterval to componentDidMount in React在 React 中将 setInterval 添加到 componentDidMount
【发布时间】:2017-08-31 13:09:13
【问题描述】:

我想每 1000 毫秒更新一次 React 组件的状态。但是,我尝试在componentDidMount 上执行setInterval,但没有运气。目前我在console.log 中得到两个结果,一个是构造函数中的空状态对象,另一个是从 API 获取的对象。如何使用 setInterval 每 1000 毫秒更新一次组件的状态?

这是我的代码:

let url = 'some-link-bla-bla';

class Basemap extends React.Component {

    constructor(props) {
        super(props);
        this.state = {};
        console.log(this.state);
    }

    render() {
        return (
            <Scene style={{ width: '100vw', height: '100vh' }} 
                    mapProperties={{ basemap: 'satellite' }} 
                    viewProperties={ this.state } />
        );
    }

    componentDidMount() {
        fetch(url)
            .then(d => d.json().then(function(d) {
                console.log(d);
            }))
            .then(d => function(d) {
                this.setState({
                  center: [
                      {latitude : d.iss_position.latitude} + ', ' + 
                      {longitude: d.iss_position.longitude}
                    ]
                })
            });
    }
}

export default Basemap;

【问题讨论】:

  • 您能否使用setInterval 添加您的尝试代码。您的代码没有
  • @IsaaK08,如果您在这里找到了正确的解决方案,请将其设置为已接受。

标签: javascript reactjs


【解决方案1】:

我将调用移至 getCenter 方法中的 fetch 方法,我将在 componentDidMount 中将其传递给 setInterval 函数

  • 在设置间隔之前调用 this.getCenter()。它会在安装组件后立即获取。

  • 用componentWillUnmount 清除间隔。它将确保您在卸载组件后 setInterval 不会触发任何获取请求。

    let url = 'some-link-bla-bla';
    
    class Basemap extends React.Component {
    
    constructor(props) {
        super(props);
        this.state = {};
        console.log(this.state);
    }
    
    render() {
        return (
            <Scene style={{ width: '100vw', height: '100vh' }} 
                    mapProperties={{ basemap: 'satellite' }} 
                    viewProperties={ this.state } />
        );
    }
    
    componentDidMount() {
        // Call this function so that it fetch first time right after mounting the component
        this.getCenter();
    
        // set Interval
        this.interval = setInterval(this.getCenter, 1000);
    }
    
    componentWillUnmount() {
        // Clear the interval right before component unmount
        clearInterval(this.interval);
    }
    
    getCenter = () => {
        fetch(url)
                .then(d => d.json().then(function(d) {
                    console.log(d);
                }))
                .then(d => function(d) {
                    this.setState({
                      center: [
                          {latitude : d.iss_position.latitude} + ', ' + 
                          {longitude: d.iss_position.longitude}
                        ]
                    })
                });
    }
    }
    
    export default Basemap;
    

【讨论】:

  • 这对我有用。只需将挂载中的 getCenter 更改为 this.getCenter()
  • setInterval 似乎只触发一次然后为我停止。
【解决方案2】:

通常使用 React 我使用 setTimeout 而不是 setInterval 唯一的对应物是您需要在函数结束后调用它。

let url = 'some-link-bla-bla';

class Basemap extends React.Component {

    constructor(props) {
        super(props);
        this.state = {};
        console.log(this.state);
        this.intervalFunc = this.intervalFunc.bind(this); // Here
        this.timeout= this.timeout.bind(this); // Here
    }

    render() {
        return (
            <Scene style={{ width: '100vw', height: '100vh' }} 
                    mapProperties={{ basemap: 'satellite' }} 
                    viewProperties={ this.state } />
        );
    }

    intervalFunc() {
        fetch(url)
            .then(d => d.json().then(function(d) {
                console.log(d);
            }))
            .then(d => function(d) {
                this.setState({
                  center: [
                      {latitude : d.iss_position.latitude} + ', ' + 
                      {longitude: d.iss_position.longitude}
                    ]
                })
                this.timeout(); // Here
            });
    }

    timeout() {
        this.setTimeout(intervalFunc, 1000); // Here
    }

    componentDidMount() {
        this.timeout(); // Here
    }
}

【讨论】:

  • 这似乎是合适的解决方案,但我得到: 第 35 行:'timeout' 未定义 no-undef 第 40 行:'intervalFunc' 未定义 no-undef 第 44 行:'timeout' 未定义定义无-undef
  • 抱歉,忘记加this.timeout()
  • 代码已更改,在timeout() 上将setTimeout() 更改为this.setTimeout()
  • 递归超时函数。整洁的东西。
  • @JosephCho 为什么它很整洁?如果服务器端返回错误,你会无休止地尝试请求直到它神奇地工作吗?这样,如果最后一次成功,它只会调用另一个超时。我并不是说它比setInterval 更好,因为它不是,setInterval 是为这种情况而设计的。只是另一种方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 2020-05-09
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多