我试图使用 web-pack 渲染简单的 React 应用程序,所有内容都可以完美编译。运行时代码失败并显示以下堆栈跟踪:
Uncaught TypeError: Cannot read property 'setState' of undefined
at checkBoxCheck (App.js:174)...
这是带有 setState 的代码:
//App.js
export class Login extends Component {
constructor(props) {
super(props);
this.state = { remember: false };
}
checkBoxCheck(event) {
this.setState({
remember: !this.state.remember
});
console.log(this.state.remember);
}
render() {
let msg = this.state.remember ? "checked" : "uncheked";
return (
<form method="post">
<h1>{msg}</h1>
<label htmlFor="login">Login: </label>
<input type="text" name="login" />
<label htmlFor="pass"> Password: </label>
<input type="password" name="pass" />
<label htmlFor="remember">Remeber me: </label>
<input
type="checkbox"
name="remember"
defaultChecked={this.state.remember}
onChange={this.checkBoxCheck}
/>
</form>
);
}
}
语法问题出在哪里?
我还尝试创建一个 checkBoxCheck '箭头' 函数,这会导致编译错误:
checkBoxCheck = event => {
this.setState((prevState, props) =>({
remember: !prevState.remember
}));
console.log(this.state.remember);
}
//output
SyntaxError: D:/Projects/Learning-projects/learn-react/src/App.js: Unexpected token (53:18)
51 | }
52 |
> 53 | checkBoxCheck = event => {
| ^
54 | this.setState((prevState, props) =>({
55 | remember: !prevState.remember
56 | }));
最佳答案
您实际上忘记将上下文绑定(bind)到 checkBoxCheck 方法。
...
<input
type="checkbox"
name="remember"
defaultChecked={this.state.remember}
onChange={this.checkBoxCheck.bind(this)} // <- .bind(this)
/>
...
<小时/>
提示:
关于您的代码很少有评论:
- 不要在
render
方法中绑定(bind)上下文。 - 请勿在
this.setState
函数中使用this.state
永远不要在渲染
中使用.bind()
render() { // <- If you here
...
<input
...
onChange={this.checkBoxCheck.bind(this)} // <- don't do this
/>
...
}
通过像这样绑定(bind)事件处理程序,每次 React 调用组件的渲染时,您都可以创建全新的函数。相反,您可以将函数转换为箭头函数:
checkBoxCheck = event => {
this.setState({
remember: !this.state.remember
});
console.log(this.state.remember);
}
并这样调用它:
...
<input
type="checkbox"
name="remember"
defaultChecked={this.state.remember}
onChange={this.checkBoxCheck} // <- there is no binding
/>
...
此外,您可以在类构造函数中绑定(bind)所有方法:
//App.js
export class Login extends Component {
constructor(props) {
super(props);
this.state = { remember: false };
this.checkBoxCheck = this.checkBoxCheck.bind(this); // <- Bind your methods here
}
...
并在不绑定(bind)的情况下调用您的函数:
...
<input
type="checkbox"
name="remember"
defaultChecked={this.state.remember}
onChange={this.checkBoxCheck} // <- there is no binding
/>
...
在 this.setState
中使用 this.state
增量函数就是一个例子:
function increment() {
this.setState({value: this.state.value + 1});
}
如果这两个 setState 操作在一个批处理中分组在一起,则其看起来将类似于以下内容(假定值为 1):
setState({value: 1 + 1})
setState({value: 1 + 1})
可以通过使用将先前状态作为第一个参数的回调来避免这种情况:
function increment() {
this.setState(prevState => ({value: prevState.value + 1}));
}
然后,即使事情是批量发生的,React 也会以正确且更新的状态调用参数。上面的例子类似于:
setState({value: 1 + 1})
setState({value: 2 + 1})
引用资料:
关于javascript - 未捕获的类型错误 : Cannot read property 'setState' of undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51254873/