获取错误:无法读取未定义的属性状态

IT技术 reactjs undefined state typeerror
2021-04-20 03:34:30
import React, { Component } from "react";
import FormUpdate from "../components/formUpdate";
import { fetchClothingItem, updateClothingItem } from "../actions/crud";

export default class Update extends Component {
    constructor(props) {
        super(props);

        this.state = {
          updateClothingItem: {}
        };
    }

    componentWillMount() {
        fetchClothingItem(this.props.match.params.postId)
        .then(data => {
        this.setState(state => {
          state.updateClothingItem = data;
          return state;
        });
        console.log("data", data);

        //HERE IT IS RETURNING EXPECTED DATA       

        console.log("this.state.updateClothingItem",this.state.updateClothingItem)    
          })
        .catch(err => {
            console.error("err", err);
        });
    }

    handleSubmit(data) {

        //HERE IT IS THROWING: 

        > "TypeError: Cannot read property 'state' of undefined"

        console.log("this.state.updateClothingItem", this.state.updateClothingItem);
            updateClothingItem(this.state.updateClothingItem.id, data); this.props.router.push("/update");
    }
    render() {
        return (
        <div>
        <FormUpdate
          //onSubmit={this.handleSubmit.bind(this)}
          id={this.state.updateClothingItem.id}
          name={this.state.updateClothingItem.name}
          sleeveLength={this.state.updateClothingItem.sleeveLength}
          fabricWeight={this.state.updateClothingItem.fabricWeight}
          mood={this.state.updateClothingItem.body}
          color={this.state.updateClothingItem.color}
        />
        <button
          type="submit"
          onClick={this.handleSubmit}
          className="addItemButton"
        >
        Button
        </button>
      </div>
    );
  }
}
3个回答

在 React 代码实现方面,有一些技术上是错误的。

首先,使用 ES6 风格的类编写,任何需要访问 Class 属性的函数都需要显式binded在您的情况下,您需要使用arrow functionof 或绑定 handleSubmit 函数binding in constructor

有关更多详细信息,请参阅此答案:为什么以及何时需要在 React 中绑定函数和事件处理程序?

其次:您在 componentWillMount 函数中设置了异步请求,并且在它的成功响应中,您正在设置状态。但是使用setStateincomponentWillMount是在组件渲染后触发的,因此您仍然需要进行未定义的检查。您应该componentDidMount为异步请求使用生命周期函数。

检查这个答案是否有AJAX 请求componentDidMountcomponentWillMount

第三: setState 是异步的,因此在 setState 函数之后记录状态值不会导致显示正确的输出。使用setState callback来代替。

有关更多详细信息,请参阅这些答案:

调用 setState 不会立即改变状态

何时使用 React setState 回调

代码:

export default class Update extends Component {
    constructor(props) {
        super(props);

        this.state = {
          updateClothingItem: {}
        };
    }

    componentDidMount() {
        fetchClothingItem(this.props.match.params.postId)
        .then(data => {
        this.setState(state => {
          state.updateClothingItem = data;
          return state;
        });
        console.log("data", data);

        //HERE IT IS RETURNING EXPECTED DATA       

        console.log("this.state.updateClothingItem",this.state.updateClothingItem)    
          }) // this statement will not show you correct result since setState is async 
        .catch(err => {
            console.error("err", err);
        });
    }

    handleSubmit = (data) =>  { .    // binding using arrow function here

        console.log("this.state.updateClothingItem", this.state.updateClothingItem);
            updateClothingItem(this.state.updateClothingItem.id, data); this.props.router.push("/update");
    }
    render() {
        return (
        <div>
        <FormUpdate
          //onSubmit={this.handleSubmit.bind(this)}
          id={this.state.updateClothingItem.id}
          name={this.state.updateClothingItem.name}
          sleeveLength={this.state.updateClothingItem.sleeveLength}
          fabricWeight={this.state.updateClothingItem.fabricWeight}
          mood={this.state.updateClothingItem.body}
          color={this.state.updateClothingItem.color}
        />
        <button
          type="submit"
          onClick={this.handleSubmit}
          className="addItemButton"
        >
        Button
        </button>
      </div>
    );
  }
}
这个绑定的东西让我每次使用函数访问状态数据时都发疯了,这在来自传统语言和 UI 框架背景的语法上真是太奇怪了
2021-05-25 03:34:30

您忘记将handleSubmit函数绑定到类。您可以使用箭头函数来定义函数。

handleSubmit=(data) =>{
...
}

或者您可以在构造函数中绑定该函数。

constructor(props) {
        super(props);
        this.state = {
          updateClothingItem: {}
        };
        this.handleSubmit= this.handleSubmit.bind(this,data);
    }

构造函数中还没有状态

如果你想在构造函数中设置状态,你可以这样做

class SomeComponent extends Component {
   constructor(props){
      super(props)

      this.state = { someKey: someValue }
   }
}

甚至像这样

class SomeComponent extends Component {

   state = { someKey: someValue }

}

但在这种情况下,应该正确配置 babel

@Jesse 刚刚更新了我的答案 - ...意味着应该有一些值
2021-06-07 03:34:30
这两者有什么区别?我在第一个例子中遇到了问题。
2021-06-21 03:34:30