为什么在 ReactJS 组件的 handleChange 方法上出现 setState 未定义错误?
Why an setState undefined error on a ReactJS Component handleChange method?
这是一个简单的用户配置文件页面 ReactJS + Reactstrap + Axios
在 handleChange 方法中使用 setState 时出现错误。
我尝试了几种设置状态的方法,但无济于事。这可能是一个更深层次的问题...或链接到 JSON 解析和字符串化。
表格显示正常。
错误堆栈:
user-form.js?c7a5:69 Uncaught TypeError: Cannot read property 'setState' of undefined
at handleChange (user-form.js?c7a5:69)
at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:237)
at invokeGuardedCallback (react-dom.development.js?61bb:292)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js?61bb:306)
at executeDispatch (react-dom.development.js?61bb:389)
at executeDispatchesInOrder (react-dom.development.js?61bb:414)
at executeDispatchesAndRelease (react-dom.development.js?61bb:3278)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js?61bb:3287)
at Array.forEach (<anonymous>)
handleChange @ user-form.js?c7a5:69
callCallback @ react-dom.development.js?61bb:188
invokeGuardedCallbackDev @ react-dom.development.js?61bb:237
invokeGuardedCallback @ react-dom.development.js?61bb:292
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js?61bb:306
executeDispatch @ react-dom.development.js?61bb:389
executeDispatchesInOrder @ react-dom.development.js?61bb:414
executeDispatchesAndRelease @ react-dom.development.js?61bb:3278
executeDispatchesAndReleaseTopLevel @ react-dom.development.js?61bb:3287
forEachAccumulated @ react-dom.development.js?61bb:3257
runEventsInBatch @ react-dom.development.js?61bb:3304
runExtractedPluginEventsInBatch @ react-dom.development.js?61bb:3514
handleTopLevel @ react-dom.development.js?61bb:3558
batchedEventUpdates @ react-dom.development.js?61bb:21871
batchedEventUpdates @ react-dom.development.js?61bb:795
dispatchEventForLegacyPluginEventSystem @ react-dom.development.js?61bb:3568
attemptToDispatchEvent @ react-dom.development.js?61bb:4267
dispatchEvent @ react-dom.development.js?61bb:4189
unstable_runWithPriority @ scheduler.development.js?3069:653
runWithPriority @ react-dom.development.js?61bb:11039
discreteUpdates @ react-dom.development.js?61bb:21887
discreteUpdates @ react-dom.development.js?61bb:806
dispatchDiscreteEvent @ react-dom.development.js?61bb:4168
用户-form.js :
const axios = require('axios');
import React from 'react';
import '!style-loader!css-loader!bootstrap/dist/css/bootstrap.css'
import { Button, Form, FormGroup, Label, Input, FormText } from 'reactstrap';
class UserForm extends React.Component {
constructor(props) {
super(props);
this.state = {
'user' : {
'firstname' : '',
'lastname' : '',
'email' : '',
'phone' : '',
'address' : '',
'zip' : '',
'city' : '',
},
};
}
componentDidMount() {
axios
.get('/api/user.php')
.then(response => (
this.setState({user:{...this.state.user,firstname: JSON.parse(JSON.stringify(response.data['FIRSTNAME']))}}),
this.setState({user:{...this.state.user,lastname: JSON.parse(JSON.stringify(response.data['LASTNAME']))}}),
this.setState({user:{...this.state.user,email: JSON.parse(JSON.stringify(response.data['EMAIL']))}}),
this.setState({user:{...this.state.user,phone: JSON.parse(JSON.stringify(response.data['MOBILE_PHONE']))}}),
this.setState({user:{...this.state.user,address: JSON.parse(JSON.stringify(response.data['ADDRESS']))}}),
this.setState({user:{...this.state.user,zip: JSON.parse(JSON.stringify(response.data['POSTAL_CODE']))}}),
this.setState({user: {...this.state.user,city: JSON.parse(JSON.stringify(response.data['CITY']))}}),
console.log({user:{...this.state.user,firstname: JSON.parse(JSON.stringify(response.data['FIRSTNAME']))}})
))
}
render() {
return(
<div className="user-form">
<Form id="user-form">
<FormGroup onChange={this.handleChange} id="user-data">
<Label id="user-firstname-label">Prénom</Label>
<Input name="firstname" id="user-firstname" type="text" defaultValue={this.state.user.firstname}/>
<Label id="user-lastname-label">Nom</Label>
<Input name="lastname" id="user-lastname" type="text" defaultValue={this.state.user.lastname}/>
<Label id="user-email-label">Adresse e-mail</Label>
<Input name="email" id="user-email" type="email" defaultValue={this.state.user.email}/>
<Label id="user-phone-label">Numéro de téléphone</Label>
<Input name="phone" id="user-phone" type="text" defaultValue={this.state.user.phone}/>
<Label id="user-address-label">Adresse</Label>
<Input name="adress" id="user-address" type="text" defaultValue={this.state.user.address}/>
<Label id="user-zip-label">Code postal</Label>
<Input name="zip" id="user-zip" type="text" defaultValue={this.state.user.zip}/>
<Label id="user-city-label">Ville</Label>
<Input name="city" id="user-city" type="text" defaultValue={this.state.user.city}/>
</FormGroup>
<Button>Sauvegarder</Button>
</Form>
</div>
);
}
handleChange(e) {
let change = ({user:{[e.target.name] : e.target.value }});
console.log(change);
this.setState(change);
//OTHER TRIES
//this.setState(JSON.stringify(change));
// this.setState({
// user: {
// ...this.state.user,
// [e.target.name]: e.target.value,
// },
// });
}
}
export default UserForm;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import UserProfile from './components/user-form'
ReactDOM.render(<UserProfile />, document.getElementById('app'));
console.log 似乎是正确的:
谢谢你的帮助!
JavaScript 中的 this
关键字与大多数面向对象语言不同:
A function's this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.
In most cases, the value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called. ES5 introduced the bind() method to set the value of a function's this regardless of how it's called, and ES2015 introduced arrow functions which don't provide their own this binding (it retains the this value of the enclosing lexical context).
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
您必须在构造函数中绑定 handleChange
方法
constructor(props) {
// ...
this.handleChange = this.handleChange.bind(this)
}
或者定义handleChange
为箭头函数:
handleChange = e => {
// ...
}
这是一个简单的用户配置文件页面 ReactJS + Reactstrap + Axios
在 handleChange 方法中使用 setState 时出现错误。
我尝试了几种设置状态的方法,但无济于事。这可能是一个更深层次的问题...或链接到 JSON 解析和字符串化。
表格显示正常。
错误堆栈:
user-form.js?c7a5:69 Uncaught TypeError: Cannot read property 'setState' of undefined
at handleChange (user-form.js?c7a5:69)
at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:237)
at invokeGuardedCallback (react-dom.development.js?61bb:292)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js?61bb:306)
at executeDispatch (react-dom.development.js?61bb:389)
at executeDispatchesInOrder (react-dom.development.js?61bb:414)
at executeDispatchesAndRelease (react-dom.development.js?61bb:3278)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js?61bb:3287)
at Array.forEach (<anonymous>)
handleChange @ user-form.js?c7a5:69
callCallback @ react-dom.development.js?61bb:188
invokeGuardedCallbackDev @ react-dom.development.js?61bb:237
invokeGuardedCallback @ react-dom.development.js?61bb:292
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js?61bb:306
executeDispatch @ react-dom.development.js?61bb:389
executeDispatchesInOrder @ react-dom.development.js?61bb:414
executeDispatchesAndRelease @ react-dom.development.js?61bb:3278
executeDispatchesAndReleaseTopLevel @ react-dom.development.js?61bb:3287
forEachAccumulated @ react-dom.development.js?61bb:3257
runEventsInBatch @ react-dom.development.js?61bb:3304
runExtractedPluginEventsInBatch @ react-dom.development.js?61bb:3514
handleTopLevel @ react-dom.development.js?61bb:3558
batchedEventUpdates @ react-dom.development.js?61bb:21871
batchedEventUpdates @ react-dom.development.js?61bb:795
dispatchEventForLegacyPluginEventSystem @ react-dom.development.js?61bb:3568
attemptToDispatchEvent @ react-dom.development.js?61bb:4267
dispatchEvent @ react-dom.development.js?61bb:4189
unstable_runWithPriority @ scheduler.development.js?3069:653
runWithPriority @ react-dom.development.js?61bb:11039
discreteUpdates @ react-dom.development.js?61bb:21887
discreteUpdates @ react-dom.development.js?61bb:806
dispatchDiscreteEvent @ react-dom.development.js?61bb:4168
用户-form.js :
const axios = require('axios');
import React from 'react';
import '!style-loader!css-loader!bootstrap/dist/css/bootstrap.css'
import { Button, Form, FormGroup, Label, Input, FormText } from 'reactstrap';
class UserForm extends React.Component {
constructor(props) {
super(props);
this.state = {
'user' : {
'firstname' : '',
'lastname' : '',
'email' : '',
'phone' : '',
'address' : '',
'zip' : '',
'city' : '',
},
};
}
componentDidMount() {
axios
.get('/api/user.php')
.then(response => (
this.setState({user:{...this.state.user,firstname: JSON.parse(JSON.stringify(response.data['FIRSTNAME']))}}),
this.setState({user:{...this.state.user,lastname: JSON.parse(JSON.stringify(response.data['LASTNAME']))}}),
this.setState({user:{...this.state.user,email: JSON.parse(JSON.stringify(response.data['EMAIL']))}}),
this.setState({user:{...this.state.user,phone: JSON.parse(JSON.stringify(response.data['MOBILE_PHONE']))}}),
this.setState({user:{...this.state.user,address: JSON.parse(JSON.stringify(response.data['ADDRESS']))}}),
this.setState({user:{...this.state.user,zip: JSON.parse(JSON.stringify(response.data['POSTAL_CODE']))}}),
this.setState({user: {...this.state.user,city: JSON.parse(JSON.stringify(response.data['CITY']))}}),
console.log({user:{...this.state.user,firstname: JSON.parse(JSON.stringify(response.data['FIRSTNAME']))}})
))
}
render() {
return(
<div className="user-form">
<Form id="user-form">
<FormGroup onChange={this.handleChange} id="user-data">
<Label id="user-firstname-label">Prénom</Label>
<Input name="firstname" id="user-firstname" type="text" defaultValue={this.state.user.firstname}/>
<Label id="user-lastname-label">Nom</Label>
<Input name="lastname" id="user-lastname" type="text" defaultValue={this.state.user.lastname}/>
<Label id="user-email-label">Adresse e-mail</Label>
<Input name="email" id="user-email" type="email" defaultValue={this.state.user.email}/>
<Label id="user-phone-label">Numéro de téléphone</Label>
<Input name="phone" id="user-phone" type="text" defaultValue={this.state.user.phone}/>
<Label id="user-address-label">Adresse</Label>
<Input name="adress" id="user-address" type="text" defaultValue={this.state.user.address}/>
<Label id="user-zip-label">Code postal</Label>
<Input name="zip" id="user-zip" type="text" defaultValue={this.state.user.zip}/>
<Label id="user-city-label">Ville</Label>
<Input name="city" id="user-city" type="text" defaultValue={this.state.user.city}/>
</FormGroup>
<Button>Sauvegarder</Button>
</Form>
</div>
);
}
handleChange(e) {
let change = ({user:{[e.target.name] : e.target.value }});
console.log(change);
this.setState(change);
//OTHER TRIES
//this.setState(JSON.stringify(change));
// this.setState({
// user: {
// ...this.state.user,
// [e.target.name]: e.target.value,
// },
// });
}
}
export default UserForm;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import UserProfile from './components/user-form'
ReactDOM.render(<UserProfile />, document.getElementById('app'));
console.log 似乎是正确的:
谢谢你的帮助!
JavaScript 中的 this
关键字与大多数面向对象语言不同:
A function's this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.
In most cases, the value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called. ES5 introduced the bind() method to set the value of a function's this regardless of how it's called, and ES2015 introduced arrow functions which don't provide their own this binding (it retains the this value of the enclosing lexical context).
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
您必须在构造函数中绑定 handleChange
方法
constructor(props) {
// ...
this.handleChange = this.handleChange.bind(this)
}
或者定义handleChange
为箭头函数:
handleChange = e => {
// ...
}