2017-12-13 2 views
0

Ich lerne React und ich erstelle eine Anwendung für mich, um mein Studium zu verfolgen. Alles funktioniert gut.Wie setze ich in meinem Fall Requisiten für den Zustand in der Komponente?

In meiner Anwendung habe ich eine klassenbasierte Komponente, in der ich Requisiten übergeben muss. Ich habe jedoch gelernt, dass ich niemals Requisiten in einer klassenbasierten Komponente weitergeben sollte, weil ich den Zustand irgendwo ändern könnte. Aber ich weiß nicht, wie ich meinen Code funktionieren lassen kann, ohne Requisiten zu übergeben, so wie ich es tue. Ich selbst studiere, also habe ich keinen Lehrer zu fragen, daher ist StackOverflow mein bester Tutor. Vielen Dank im Voraus für Ihre Hilfe.

Dies ist mein Code.Ich habe ihn entsprechend in eine Antwort geändert und es funktioniert jetzt gut, aber gibt es irgendetwas, das ich in meinem Code ändern oder vermeiden sollte?

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

Yeah doing so wird machen, was auch immer den Zustand unveränderbar machen –

+0

bei der Verwendung von Requisiten, müssen Sie Handler zur Verfügung stellen, um die Requisiten zu modifizieren –

Antwort

1

Verwenden Sie die Lebenszyklusmethode componentWillMount(). Setze die Zeit als 0 für den Anfangswert. componentWillMount() berechnet die Zeit und den gesetzten Zustand. Es wird nur beim ersten Laden der Komponente ausgeführt. sonst verwende componentWillRecieveProps();

Haftungsausschluss: componentWillMount() wird ausgeführt, nur einmal und Aktualisierungen zu den Requisiten werden nicht in der Kindkomponente widerspiegeln.

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,}); 
} 

denken Sie daran, es ist immer eine schlechte Praxis, Requisiten sogar in der Art, wie ich vorgeschlagen, zu setzen. Der beste Weg wäre, den berechneten Wert als Requisiten an die untergeordnete Komponente zu senden. und verwende this.props.timeRun. Diese verhindert unerwünschte Schleifen und Updates.

+0

Vielen Dank. Ich werde es versuchen, wenn ich zu Hause bin – Nhat

+0

Vielen Dank können Sie bitte einen Blick auf meine volle Komponente und geben Sie mir Ihre Meinung dazu? Gibt es etwas, das ich in meinem Code vermeiden sollte? danke – Nhat

+0

sieht für mich ok aus. –

1

Ich schlage vor, es in eine Lebenszyklusmethode zu platzieren, componentWillReceiveProps(). Dort können Sie verwalten, wann Sie Status mit Requisiten synchronisieren müssen und wann nicht.

Verwandte Themen