出现错误:无法读取未定义的属性状态
Posted
技术标签:
【中文标题】出现错误:无法读取未定义的属性状态【英文标题】:getting error: Cannot read property state of undefined 【发布时间】:2018-04-12 03:04:46 【问题描述】: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>
);
【问题讨论】:
【参考方案1】:构造函数中还没有状态
如果你想在构造函数中设置状态,你可以这样做
class SomeComponent extends Component
constructor(props)
super(props)
this.state = someKey: someValue
甚至像这样
class SomeComponent extends Component
state = someKey: someValue
但在这种情况下,babel 应该正确配置
【讨论】:
这两者有什么区别?我遇到了第一个例子的问题。 @Jesse 刚刚更新了我的答案 - ... 意味着应该有一些值【参考方案2】:在 React 代码实现方面存在一些技术上的错误。
首先, 使用 ES6 编写类的风格,任何需要访问 Class 属性的函数都需要显式地binded
。在您的情况下,您需要使用arrow function
of 或binding in constructor
绑定handleSubmit 函数。
更多详情请查看此答案:Why and when do we need to bind functions and eventHandlers in React?
其次:您在 componentWillMount 函数中设置了异步请求,并且在它的成功响应中,您正在设置状态。但是在渲染组件后会触发在componentWillMount
中使用setState
,因此您仍然需要进行未定义的检查。您应该使用 componentDidMount
生命周期函数来处理异步请求。
检查这个答案是否有AJAX request in componentDidMount
or componentWillMount
第三: setState 是异步的,因此在 setState 函数之后记录状态值不会导致显示正确的输出。请改用setState callback
。
查看这些答案了解更多详情:
calling setState doesn't mutate state immediately
When to use React setState callback
代码:
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 框架背景,真是太奇怪了【参考方案3】:您忘记将 handleSubmit
函数绑定到该类。您可以使用箭头函数来定义函数。
handleSubmit=(data) =>
...
或者你可以在你的构造函数中绑定函数。
constructor(props)
super(props);
this.state =
updateClothingItem:
;
this.handleSubmit= this.handleSubmit.bind(this,data);
【讨论】:
以上是关于出现错误:无法读取未定义的属性状态的主要内容,如果未能解决你的问题,请参考以下文章
ReactJS TypeError:无法读取未定义的属性“setState”[重复]
下一个 redux 包装器出现无法读取未定义的属性 'getState' 的错误