Reactjs 在我的例子中,如何将道具设置为组件中的状态?

Reactjs 在我的例子中,如何将道具设置为组件中的状态?,reactjs,redux,state,react-props,Reactjs,Redux,State,React Props,我正在学习React,我正在为自己创建一个应用程序来跟踪我的学习。一切正常 在我的应用程序中,我有一个基于类的组件,其中我必须将道具传递给state。然而,我已经了解到,我不应该在基于类的组件中向状态传递道具,因为我可能会在某个地方更改状态。但我不知道如何让我的代码在不向州政府传递道具的情况下工作,就像我正在做的一样。我在自学,所以我没有老师可以问,所以StackOverflow是我最好的导师。提前感谢您的帮助 这是我的代码。我根据下面的答案对其进行了相应的更改,现在可以正常工作了,但我的代码中

我正在学习React,我正在为自己创建一个应用程序来跟踪我的学习。一切正常

在我的应用程序中,我有一个基于类的组件,其中我必须将道具传递给state。然而,我已经了解到,我不应该在基于类的组件中向状态传递道具,因为我可能会在某个地方更改状态。但我不知道如何让我的代码在不向州政府传递道具的情况下工作,就像我正在做的一样。我在自学,所以我没有老师可以问,所以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)
从“React”导入React;
从“/SubjectForm”导入SubjectFrom;
从“../actions/subjectAction”导入{StartObject};
从'react redux'导入{connect};
类BeginObject扩展了React.Component{
建造师(道具){
超级(道具);
这个州={
时间运行:0,
onFinish:“”,
按钮更改:“开始”,
计时器:空
}
}
组件willmount(){
this.setState({timeRun:this.props.subject?this.props.subject.hour*60*60+this.props.subject.minute*60:0,});
}
组件将卸载(){
让小时=数学地板(this.state.timeRun/(60*60));
让分钟=数学地板((this.state.timeRun%(60*60))/60);
这个。onPause();
if(本道具主题){
this.props.dispatch(startObject(this.props.subject.id,{hour,minute}))
console.log(this.props.subject.id)
}
}
onStart=()=>{
clearInterval(这个.timer)
this.timer=setInterval(()=>{
让计数=this.state.timeRun
计数--
如果(计算){
clearInterval(这个.timer)
让时间=this.props.subject?this.props.subject.hour*60*60+this.props.subject.minute*60:0;
如果(this.state.timeRun{
const resetConfirm=confirm('您尚未完成,是否要重置?')
如果(重置确认===真){
clearInterval(这个.timer)
this.setState({timeRun:this.props.subject?this.props.subject.hour*60*60+this.props.subject.minute*60:0,
onFinish:“”,
按钮更改:“开始”,
计时器:null})
}
}
render(){
返回(
{this.props.subject?this.props.subject.subjectName:'现在没什么事'}

{this.props.subject?`你有${this.props.subject.hour}小时和${this.props.subject.minute}分钟的工作时间`:'没有时间设定'}

{this.state.buttonChange} 暂停 重置 {this.state.onFinish}

) } }; 常量mapStateToProps=(状态、道具)=>{ 返回{ subject:state.subjects.find((subject)=>subject.id==props.match.params.id) }; } 导出默认连接(MapStateTops)(BeginObject)
我建议将其放在生命周期方法componentWillReceiveProps()中。在那里,您可以管理何时必须与props同步状态,何时不需要与props同步状态。

我建议将其放在生命周期方法componentWillReceiveProps()中。您可以在那里管理何时必须与道具同步状态以及何时不同步状态。

为此使用componentWillMount()生命周期方法。将时间运行设置为0作为初始值。componentWillMount()将计算时间并设置状态。它将仅在首次加载组件时执行。否则,请使用ComponentWillReceiveProps()

免责声明: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。这可以防止不必要的循环和更新

使用组件willmount()此的生命周期方法。将初始值的时间运行设置为0。componentWillMount()将计算时间并设置状态。它将仅在第一次加载组件时执行。否则,请使用ComponentWillReceiveProps()

免责声明: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。这可以防止不必要的循环和更新

是的,这样做会使使用道具时状态不可更改,y你需要提供处理程序来修改道具你这样做会使任何状态不可更改使用道具时,你需要提供处理程序来修改道具谢谢。我回家后会试试。非常感谢。你能看一下我的完整组件并给出你的意见吗?有什么我应该避免的吗我的代码?谢谢对我来说没问题。谢谢。我回家后会试试的。非常感谢。你能看看我的完整组件并给我你的意见吗?我的代码中有什么我应该避免的吗?谢谢对我来说没问题。