2017-12-13 31 views
0

나는 React를 배우고 있으며, 내 공부를 계속하기 위해 자신을위한 응용 프로그램을 만들고 있습니다. 모든 것이 잘 작동합니다.필자의 경우 구성 요소에 소품을 진술하는 방법은 무엇입니까?

내 응용 프로그램에는 소품을 전달해야하는 클래스 기반 구성 요소가 있습니다. 그러나 나는 어딘가에서 상태를 잠재적으로 바꿀 수 있기 때문에 클래스 기반 구성 요소에서 소품을 절대로 통과해서는 안된다는 것을 배웠습니다. 하지만 내가하고있는 것처럼 소품을 국가에 전달하지 않고 코드를 작동시키는 법을 모르겠습니다. 나는 강사가 없기 때문에 스스로 공부하고 있습니다. 따라서 StackOverflow가 최고의 교사입니다. 당신의 도움에 미리 감사드립니다.

이것은 내 코드입니다. 아래 답변에 따라 적절하게 변경되었지만 지금은 문제가 없지만 코드에서 변경하거나 피할 것이 있습니까?

import React from 'react'; 
import SubjectFrom from './SubjectForm'; 
import {startSubject} from '../actions/subjectAction'; 
import {connect} from 'react-redux'; 

class BeginSubject extends React.Component{ 
    constructor(props){ 
     super(props); 
     this.state={ 
      timeRun:0, 
      onFinish:'', 
      buttonChange:'start', 
      timer:null 
     } 
    } 

    componentWillMount(){ 
     this.setState({timeRun:this.props.subject?this.props.subject.hour*60*60+this.props.subject.minute*60:0,}); 
    } 

    componentWillUnmount(){ 
     let hour = Math.floor(this.state.timeRun/(60 * 60)); 
     let minute= Math.floor((this.state.timeRun % (60 * 60))/60); 
     this.onPause(); 
     if(this.props.subject){ 
      this.props.dispatch(startSubject(this.props.subject.id,{hour,minute})) 
      console.log(this.props.subject.id) 
     } 
    } 

    onStart=()=>{ 
     clearInterval(this.timer) 
     this.timer = setInterval(()=>{ 
      let count=this.state.timeRun 
      count-- 
      if(count<0){ 
       this.setState({onFinish:'well Done'}) 
       clearInterval(this.timer); 
       return; 
      } 
       let hourleft = Math.floor(count/(60 * 60)); 
       let minuteleft = Math.floor((count % (60 * 60))/60); 
       let secondleft = count % 60; 

       this.setState({onFinish:`you have ${hourleft} hour ${minuteleft} minute and ${secondleft} second until reaching your goal`}); 
       this.setState({timeRun:count}) 
     },1000) 
    } 

    onPause=()=>{ 
     clearInterval(this.timer) 
     let time = this.props.subject?this.props.subject.hour*60*60+this.props.subject.minute*60:0; 
     if(this.state.timeRun<time){ 
      this.setState({buttonChange:'resume'}) 
      return; 
     } 
    } 

    onReset=()=>{ 
     const resetConfirm=confirm('you have not finished, do you want to reset?') 
     if(resetConfirm===true){ 
      clearInterval(this.timer) 
      this.setState({timeRun:this.props.subject?this.props.subject.hour*60*60+this.props.subject.minute*60:0, 
          onFinish:'', 
          buttonChange:'start', 
          timer:null}) 

     } 
    } 

    render(){ 
     return(
      <div> 
       <p>{this.props.subject?this.props.subject.subjectName:'there is nothing to do for now'}</p> 
       <p>{this.props.subject?`you have ${this.props.subject.hour} hour and ${this.props.subject.minute} minute to work`:'there is no time set'}</p> 
       <button onClick={this.onStart}>{this.state.buttonChange}</button> 
       <button onClick={this.onPause}>pause</button> 
       <button onClick={this.onReset}>reset</button> 
       <p>{this.state.onFinish}</p> 
      </div> 
     ) 
    } 
}; 

const mapStateToProps=(state,props)=>{ 
    return{ 
     subject:state.subjects.find((subject)=>subject.id===props.match.params.id) 
    }; 
} 
export default connect(mapStateToProps)(BeginSubject) 
+0

그래, 그렇게하면 상태를 바꿀 수 없게 만들 것입니다. –

+0

소품을 사용할 때는 소품을 수정하기 위해 핸들러를 제공해야합니다. –

답변

1

이 경우 componentWillMount() 수명주기 메소드를 사용하십시오. 시간은 0으로 설정합니다. componentWillMount()는 시간과 상태를 계산합니다. 구성 요소가 처음로드 될 때만 실행됩니다. 그렇지 않으면 componentWillRecieveProps()를 사용하십시오.

면책 조항 : componentWillMount는() 한 번만 실행되고 소품에 대한 업데이트는 늘 아이 컴퍼넌트에 반영.

this.state={ 
     timeRun:0, 
     onFinish:'', 
     buttonChange:'start', 
     timer:null 
    } 


componentWillMount(){ 
    this.setState({timeRun:this.props.subject?this.props.subject.hour*60*60+this.props.subject.minute*60:0,}); 
} 

항상 내가 제안한 방식으로도 소품을 설정하는 것은 나쁜 습관을 기억하십시오. 가장 좋은 방법은 으로 계산 된 값을 자식 구성 요소에 소품으로 보냅니다. this.props.timeRun을 사용하십시오. 이 은 원하지 않는 루프와 업데이트를 방지합니다..

+0

감사합니다. 나는 집에있을 때 그것을 시도 할 것입니다. – Nhat

+0

대단히 감사합니다. 제 전체 구성 요소를 살펴보고 그것에 대해 당신의 의견을 말해 주시겠습니까? 내 코드에서 피해야 할 것이 있습니까? 덕분에 – Nhat

+0

나에게 괜찮아 보이는구나. –

1

lifecycle 메서드 인 componentWillReceiveProps()에 배치하는 것이 좋습니다. 여기에서 소품과 상태를 동기화해야하는 시점과 그렇지 않은 시점을 관리 할 수 ​​있습니다.