【问题标题】:How to set props to state in component in my case?在我的情况下,如何将道具设置为组件中的状态?
【发布时间】:2018-05-27 03:20:10
【问题描述】:

我正在学习 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)

【问题讨论】:

  • 是的,这样做会使状态不可改变
  • 使用props时,需要提供handlers来修改props

标签: reactjs redux state react-props


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    为此使用 componentWillMount() 生命周期方法。将运行时间设置为 0 作为初始值。 componentWillMount() 将计算时间并设置状态。它只会在第一次加载组件时执行。否则使用 componentWillRecieveProps();

    免责声明:componentWillMount() 只会执行一次,任何对 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,});
    }
    

    请记住,即使按照我建议的方式设置道具也是一种不好的做法。最好的方法是将计算值作为 props 发送到子组件。并使用 this.props.timeRun。这可以防止不必要的循环和更新

    【讨论】:

    • 谢谢。我回家的时候试试看
    • 非常感谢您能看看我的完整组件并给我您的意见吗?我的代码中有什么我应该避免的吗?谢谢
    • 我觉得不错。
    猜你喜欢
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 2018-02-16
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 2017-09-23
    相关资源
    最近更新 更多