2017-07-29 81 views
-2

我一直在玩一个我无法理解的错误。这里是我用于渲染页面的代码。React Js在setState调用时出错

export class ResourceEdit extends React.Component { 

    constructor(props) { 
    super(props); 
    this.state = {"resource" : ""} 
    } 

    getInitialState() { 
    return {successVisible: false}; 
    } 

    componentDidMount() { 
    this.loadData(); 
    } 

    componentDidUpdate(prevProps) { 
    console.log("ResourceEdit: componentDidUpdate", prevProps.params.id, this.props.params.id); 
    if (this.props.params.id != prevProps.params.id) { 
     this.loadData(); 
    } 
    } 

    loadData() { 
    $.ajax('/api/resources/' + this.props.params.id) .done(function(resource) { 
     this.setState(resource); 
    }.bind(this)); 

    } 

    onChangeCategory(e) { 
    this.setState({category: e.target.value}); 
    } 
    onChangeSubcategory(e) { 
    this.setState({subcategory: e.target.value}); 
    } 
    onChangeProduct(e) { 
    this.setState({product: e.target.value}); 
    } 
    onChangeSolution(e) { 
    this.setState({solution: e.target.value}); 
    } 
    onChangeWeight(e) { 
    this.setState({weight: e.target.value}); 
    } 
    onChangeNSOC(e) { 
    this.setState({nsoc: e.target.value}); 
    } 
    onChangeStatus(e) { 
    this.setState({status: e.target.value}); 
    } 

    onChangeDateproductadded(e) { 
    this.setState({date_product_added: e.target.value}); 
    } 
    onChangeDesignstatus(e) { 
    this.setState({design_status: e.target.value}); 
    } 
    onChangeDesigncombined(e) { 
    this.setState({design_combined: e.target.value}); 
    } 
    onChangeImplementstatus(e) { 
    this.setState({implement_status: e.target.value}); 
    } 
    onChangeImplementcombined(e) { 
    this.setState({implement_combined: e.target.value}); 
    } 
    onChangeOperatestatus(e) { 
    this.setState({operate_status: e.target.value}); 
    } 
    onChangeOperatecombined(e) { 
    this.setState({operate_combined: e.target.value}); 
    } 
    submit(e) { 
    e.preventDefault(); 
    var resource = { 
     subcategory: this.state.subcategory, 
     category: this.state.category, 
     product: this.state.product, 
     solution: this.state.solution, 
     weight: this.state.weight, 
     nsoc: this.state.nsoc, 
     status: this.state.status, 
     date_product_added: this.state.date_product_added, 
     design_status: this.state.design_status, 
     design_combined: this.state.design_combined, 
     implement_status: this.state.implement_status, 
     implement_combined: this.state.implement_combined, 
     operate_status: this.state.operate_status, 
     operate_combined: this.state.operate_combined 
    } 

    $.ajax({ 
     url: '/api/resources/' + this.props.params.id, type: 'POST', contentType:'application/json', 
     data: JSON.stringify(resource), 
     dataType: 'json', 
     success(resource) { 
     this.setState(resource); 
     this.showSuccess(); 
     } 
    }); 
    } 

    render() { 
    var success = (
     <Alert bsStyle="success" onDismiss={this.dismissSuccess} dismissAfter={5000}> 
     Resource saved to DB successfully. 
     </Alert> 
    ); 

    return (
     <div style={{maxWidth: 600}}> 
     <Panel header={"Edit resource: " + this.props.params.id}> 
      <form onSubmit={this.submit}> 
      <Input type="text" label="Category" value={this.state.category} onChange={this.onChangeCategory}/> 
      <Input type="text" label="Sub Category" value={this.state.subcategory} onChange={this.onChangeSubcategory}/> 
      <Input type="text" label="Product" value={this.state.product} onChange={this.onChangeProduct}/> 
      <Input type="text" label="Solution" value={this.state.solution} onChange={this.onChangeSolution}/> 
      <Input type="text" label="Weight" value={this.state.weight} onChange={this.onChangeWeight}/> 
      <Input type="text" label="NSOC" value={this.state.nsoc} onChange={this.onChangeNSOC}/> 
      <Input type="text" label="Status" value={this.state.status} onChange={this.onChangeStatus}/> 
      <Input type="text" label="Date" value={this.state.date_product_added} onChange={this.onChangeDateproductadded}/> 
      <Input type="text" label="Design Status" value={this.state.design_status} onChange={this.onChangeDesignstatus}/> 
      <Input type="text" label="Design Players" value={this.state.design_combined} onChange={this.onChangeDesigncombined}/> 
      <Input type="text" label="Implement Status" value={this.state.implement_status} onChange={this.onChangeImplementstatus}/> 
      <Input type="text" label="Implement Players" value={this.state.implement_combined} onChange={this.onChangeImplementcombined}/> 
      <Input type="text" label="Operate Status" value={this.state.operate_status} onChange={this.onChangeOperatestatus}/> 
      <Input type="text" label="Operate Players" value={this.state.operate_combined} onChange={this.onChangeOperatecombined}/> 
      <ButtonToolbar> 
       <Button type="submit" bsStyle="primary">Submit</Button> 
       <Link className="btn btn-link" to="/home">Back</Link> 
      </ButtonToolbar> 
      </form> 
     </Panel> 
     {this.state.successVisible ? success : null} 
     </div> 
    ); 
    } 
} 

我得到在页面加载的错误,说 未捕获的错误:的setState(...):需要的状态变量的目的是更新或返回状态变量的对象的功能。 在不变(EVAL在

请人帮我找出什么是错的这个代码。在此先感谢..

+0

* at ... * ?????? –

+3

显然,在你调用'setState'的某个地方,你没有传入*“要更新的状态变量对象或返回状态变量对象的函数”*。所以......调试并找出原因。调试是一项基本的技能,不是高级技能。这是学习的第一件事情之一。 –

+1

ajax响应返回什么? json?请编辑问题并添加API响应 – Kaushal

回答

-1

当你在一个函数调用this.setState(),确保与this绑定。在这种例如,您可能需要绑定所有的onChange功能与this

您可以在constructor约束他们,那么你不必担心它还是在渲染功能绑定。

constructor(props) { 
    super(props); 
    this.state = {"resource" : ""}  

    this.loadData = this.loadData.bind(this) 
    this.onChangeCategory = this.onChangeCategory.bind(this) 
    this.onChangeSubcategory = this.onChangeSubcategory.bind(this) 
    // and more methods to bind... 
} 

通过这种练习,您不需要在ajax调用中使用bind(this),这可以使代码干净整洁。

希望这会有所帮助!