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>
);
}
}
답변
handleSubmit
함수를 클래스에 바인딩하는 것을 잊었습니다. 화살표 함수를 사용하여 함수를 정의 할 수 있습니다.
handleSubmit=(data) =>{
...
}
또는 생성자에서 함수를 바인딩 할 수 있습니다.
constructor(props) {
super(props);
this.state = {
updateClothingItem: {}
};
this.handleSubmit= this.handleSubmit.bind(this,data);
}
리액트 코드 구현과 관련하여 기술적으로 잘못된 점이 몇 가지 있습니다.
첫째, 클래스를 작성하는 ES6 스타일에서는 Class 속성에 액세스해야하는 모든 함수가 명시 적으로 binded
이어야합니다. 귀하의 경우에는 arrow function
또는 binding in constructor
을 사용하여 handleSubmit 함수를 바인드해야합니다.
둘째 : 당신은 당신의 비동기 요청이 componentWillMount 기능과 그것의 성공 응답에 설정되어, 당신이 설정하고있는 상태. 그러나 setState
을 componentWillMount
에 사용하면 구성 요소가 렌더링 된 후에 트리거되므로 정의되지 않은 검사가 필요합니다. 대신 비동기 요청의 경우 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>
);
}
}