2016-10-20 3 views
1

다음 구성 요소 코드를 사용하여 카운트 다운 타이머를 표시하려고합니다.하지만 계속 경고 메시지가 표시됩니다.React 구성 요소 경고 setState (...) : 탑재 된 구성 요소 또는 장착 된 구성 요소 만 업데이트 할 수 있습니다.

: 내 isMounted 상태 변수는 전역 사실이라면 난 단지 확인 후 상태를 설정 한 가정, 그러나

"을 경고 setState를 (...)는 만 장착 또는 구성 요소 를 장착 업데이트 할 수" 구성 요소. 내 실수는 어디 갔지?

import React, { Component, PropTypes } from 'react' 

export default class CountDownTimerContainer extends Component { 
    static propTypes = { 
    initialTimeRemaining: PropTypes.number.isRequired, 
    interval: PropTypes.number, 
    formatFunc: PropTypes.func, 
    tickCallback: PropTypes.func, 
    completeCallback: PropTypes.func 
    } 

    constructor (props) { 
    super(props) 
    this.state = { 
     timeRemaining: this.props.initialTimeRemaining, 
     timeoutId: null, 
     prevTime: null, 
     isMounted: false 
    } 
    } 

    componentWillMount() { 
    this.setState({isMounted: true}) 
    } 

    componentDidMount() { 
    this.tick() 
    } 

    componentWillReceiveProps (newProps) { 
    if (this.state.timeoutId) { 
     clearTimeout(this.state.timeoutId) 
    } 
    if (this.state.isMounted) { 
     this.setState({prevTime: null, timeRemaining: newProps.initialTimeRemaining}) 
    } 
    } 

    componentDidUpdate() { 
    if ((!this.state.prevTime) && this.state.timeRemaining > 0 && this.state.isMounted) { 
     this.tick().bind(this) 
    } 
    } 

    componentWillUnmount() { 
    this.setState({isMounted: false}) 
    clearTimeout(this.state.timeoutId) 
    } 

    tick() { 
    const currentTime = Date.now() 
    const dt = this.state.prevTime ? (currentTime - this.state.prevTime) : 0 
    const interval = this.props.interval 

    // correct for small variations in actual timeout time 
    const timeRemainingInInterval = (interval - (dt % interval)) 
    let timeout = timeRemainingInInterval 

    if (timeRemainingInInterval < (interval/2.0)) { 
     timeout += interval 
    } 

    const timeRemaining = Math.max(this.state.timeRemaining - dt, 0) 
    const countdownComplete = (this.state.prevTime && timeRemaining <= 0) 

    if (this.state.isMounted) { 
     if (this.state.timeoutId) { 
     clearTimeout(this.state.timeoutId) 
     } 
     this.setState({ 
     timeoutId: countdownComplete ? null : setTimeout(this.tick.bind(this), timeout), 
     prevTime: currentTime, 
     timeRemaining: timeRemaining 
     }) 
    } 

    if (countdownComplete) { 
     if (this.props.completeCallback) { 
     this.props.completeCallback() 
     } 
     return 
    } 

    if (this.props.tickCallback) { 
     this.props.tickCallback(timeRemaining) 
    } 
    } 

    getFormattedTime (milliseconds) { 
    if (this.props.formatFunc) { 
     return this.props.formatFunc(milliseconds) 
    } 

    var totalSeconds = Math.round(milliseconds/1000) 

    var seconds = parseInt(totalSeconds % 60, 10) 
    var minutes = parseInt(totalSeconds/60, 10) % 60 
    var hours = parseInt(totalSeconds/3600, 10) 

    seconds = seconds < 10 ? '0' + seconds : seconds 
    minutes = minutes < 10 ? '0' + minutes : minutes 
    hours = hours < 10 ? '0' + hours : hours 

    return hours + ':' + minutes + ':' + seconds 
    } 

    render() { 
    var timeRemaining = this.state.timeRemaining 
    return (
     <div className='timer'> 
     {this.getFormattedTime(timeRemaining)} 
     </div> 
    ) 
    } 
} 

CountDownTimerContainer.defaultProps = { 
    interval: 1000, 
    formatFunc: null, 
    tickCallback: null, 
    completeCallback: null 
} 

업데이트 :에도 ComponentWIllMount에서

this.setState({isMounted: true}) 

을 제거하고 난 여전히 setStateError를 얻을 수 this.state({isMounted: true})로 생성자에 추가 한 후.

+0

4 가지 중 'setState'를 호출하면 어떤 일이 발생합니까? –

+0

글쎄 그것은 내가 생각하기에 잘못된 것입니다 : 컴포넌트가 아직 마운트되지 않았을 때'componentWillMount'에서'setState'를 사용합니다. 나는 그곳에 국가를 세울 필요가 있는지 물어 본다. –

+0

componentDidMount로 옮깁니다 – abhirathore2006

답변

1

구성 요소를 장착하기 전에 문자 그대로 .setState()을 작성하십시오 (componentWillMount()). 구성 요소가 아직 존재하지 않기 때문에 그렇게 할 수 없습니다. 오히려 초기 상태로 constructor()에 넣으십시오.

+0

setState를 componentDidMount()로 이동하면 카운터가 작동을 멈추고 componentDidMount에서 setState를 사용하지 않는 린트 오류가 발생합니다. – jasan

+0

예, 미안합니다. 그것을'constructor()'에'this.state = {}'로 넣으십시오. 그것이 초기 상태입니다. –

+0

그랬지만 여전히 setState 오류가 발생합니다. – jasan

관련 문제