React Js在setState调用时给出错误

时间:2017-07-29 13:41:06

标签: javascript reactjs

我一直在玩一个我无法理解的错误。这是我用于渲染页面的代码。

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 at

请有人帮我弄清楚这段代码有什么问题。提前谢谢..

1 个答案:

答案 0 :(得分:-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),这可以使代码干净整洁。

希望这有帮助!