2017-07-29 82 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),這可以使代碼乾淨整潔。

希望這會有所幫助!