反应:在构造函数上绑定方法时,在 setState 内实现计时器,状态属性未定义

Posted

技术标签:

【中文标题】反应:在构造函数上绑定方法时,在 setState 内实现计时器,状态属性未定义【英文标题】:React: implementing timer, state property undefined inside setState while method being bind on Constructor 【发布时间】:2019-01-23 23:54:14 【问题描述】:

我正在尝试在 React 中实现一个简单的计时器组件,该组件在道具更新时开始运行。一切正常,但计时器。 • 正确接收和处理道具。 • 状态的初始“秒”属性在构造函数中定义。

但是 this.state 在 this.setState 中是未定义的,通过异步方法 setInterval 从 componentDidMount 调用来运行计时器。

我还尝试在构造函数中将 startTimer 方法绑定到 this,但它会引发相同的错误。 this.startTimer = this.startTimer.bind(this);

这里是组件&提前谢谢你:

import React,  Component  from 'react';
import  connect  from "react-redux";

class Timer extends Component 
    constructor(props) 
        super(props);
        this.state =  seconds: 0 
        this.intervalHandle;
    

//Component receives this.props.started === true properly
    componentDidMount() 
        if (this.props.started) 
            this.startTimer();
        
    
//startTimer triggers correctly logging "STARTING" 
    startTimer() 
        console.log("STARTING")
        this.intervalHandle = setInterval(
            this.tick, 1000);
    
//tick also triggers correctly logging "Ticking" every 1000ms
    tick() 
        console.log("TICKING")
//HERE IS THE ERROR: Uncaught TypeError: Cannot read property
//'seconds' of undefined, the console throws it once a seconds
        this.setState( seconds: this.state.seconds + 1 )
    
    componentWillUnmount() 
        if (!this.props.started) 
            clearInterval(this.intervalHandle);
        
    
// Component initialy renders
    render() 
        return <span>:0this.state.seconds</span>
    

function mapStateToProps(state) 
    return 
        started: state.isStarted
    

export default connect(mapStateToProps)(Timer);

【问题讨论】:

你需要在构造函数中绑定tick(),这就是它试图访问this.state的地方。 @Jayce444,谢谢。这样就解决了问题。 【参考方案1】:

未定义的原因是 this.tick 是一个函数并且您没有绑定它。

改成

 this.intervalHandle = setInterval(this.tick.bind(this), 1000);

或者在构造函数中绑定

 constructor(props)
       super(props);
       this.tick = this.tick.bind(this);
  

 this.intervalHandle = setInterval(this.tick, 1000);

或使用箭头函数

 this.intervalHandle = setInterval(() => this.tick(), 1000);

 tick = () => 
    console.log("TICKING")
    this.setState( seconds: this.state.seconds + 1 )

这两项更改都应该可以解决您的问题

【讨论】:

谢谢!!! Hemadri Dasari,你是完全正确的。两种解决方案都有效。

以上是关于反应:在构造函数上绑定方法时,在 setState 内实现计时器,状态属性未定义的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中仅禁用 setState 消息警告

在回调函数中使用 setState 挂钩时反应过多的重新渲染

反应setState函数和复杂对象[重复]

无法理解react.js中的处理事件[关闭]

react setState

在solidity合约实例承诺中反应setState