反应:' this.state'父组件的内容在子组件函数中未定义

时间:2017-07-03 08:28:22

标签: javascript reactjs react-jsx

我正在ReactJS开发一个在线商店的订单表格。现在我在浏览器控制台中收到消息,例如' this.state'在组件函数中未定义...有什么问题?我该如何避免这个问题?我没有在官方文件中找到任何线索。

class Service extends React.Component {
    constructor(props){
        super(props);
        this.state  = {active:      false,}
    }
    clickHandler(){
        let active = !this.state.active;
        this.setState({active: active});
        this.props.addTotal((active == true ? this.props.price : -this.props.price));
    }
    render(){
        return(
            <p className={this.state.active ? 'active' : ''} onClick={() => this.clickHandler()}>
                {this.props.name} <b>${this.props.price.toFixed(2)}</b>
            </p>
        );  
    }
};

class OrderForm extends React.Component {
    constructor(){
        super();
        this.state  = { total:  0,}
    }   
    addTotal(price){
        this.setState({total: this.state.total + price});
    }
    serviceList(){
        var self    =   this;
        //Iteration with map method
        const serviceMapIterator = this.props.services.map(function(item, i, arr){
                return (<Service    key     =   {i.toString()} 
                                    name    =   {item.name} 
                                    price   =   {item.price} 
                                    active  =   {item.active} 
                                    addTotal=   {self.addTotal} >
                        </Service>);
        });
        return serviceMapIterator;
    }
    render(){
        let service =   this.serviceList();
        return(
            <div>
                {service}
                <p id={'total'}>Total <b>${this.state.total.toFixed(2)}</b></p>
            </div>
        );
    }
};
var services = [
    { name: 'Web Development',  price: 300 },
    { name: 'Design', price: 400 }
];

我该如何更改?有什么问题?

2 个答案:

答案 0 :(得分:0)

从Service(子类)调用OrderForm(父类)中定义的addTotal()方法。您需要addTotal才能访问父类的“状态”。所以你要改变你的代码 对于构造函数(),通过添加.bind(this)行:

    constructor(){
        super();
        this.state  = { total:  0,};
        this.addTotal = this.addTotal.bind(this);
    }

或者对于serviceList()方法,在javascript方法的.map()之后添加.bind(this)。请看下面的内容:

    serviceList(){
        var self    =   this;
        //Iteration with map method
        const serviceMapIterator = this.props.services.map(function(item, i, arr){
                return (<Service    key     =   {i.toString()} 
                                    name    =   {item.name} 
                                    price   =   {item.price} 
                                    active  =   {item.active} 
                                    addTotal=   {self.addTotal} >
                        </Service>);
        }.bind(this));
        return serviceMapIterator;
    }

答案 1 :(得分:0)

调用addTotal时,这不会引用 OrderForm 组件的上下文。您应该在构造函数中绑定 addTotal 函数:

constructor() {
  ...
  this.addTotal = this.addTotal.bind(this)
}

您的 addTotal 功能如下所示:

addTotal(price){
        this.setState({total: this.state.total + price});
}

根据DOCS

你不应该写

this.setState({total: this.state.total + price});

您应该使用第二种形式的setState接受一个回调函数,该函数接收previousState和previousProps作为参数。

addTotal(price) {
  this.setState((prevState, previousProps) => ({
    counter: prevState.total + price
  }));
}

clickHandler 功能需要进行类似的更改。