我正在尝试使用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'arrow'函数,该函数会导致编译错误:
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 | }));
答案 0 :(得分:3)
您实际上忘记了将上下文绑定到checkBoxCheck方法。
...
<input
type="checkbox"
name="remember"
defaultChecked={this.state.remember}
onChange={this.checkBoxCheck.bind(this)} // <- .bind(this)
/>
...
关于您的代码的评论很少:
render
this.state
中的this.setState
.bind()
通过像这样绑定事件处理程序,可以在每次React调用组件的渲染器时创建全新的函数。相反,您可以将函数转换为箭头函数:
render
并这样称呼它:
render() { // <- If you here
...
<input
...
onChange={this.checkBoxCheck.bind(this)} // <- don't do this
/>
...
}
此外,您可以在类构造函数中绑定所有方法:
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
/>
...
//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
}
...
中使用...
<input
type="checkbox"
name="remember"
defaultChecked={this.state.remember}
onChange={this.checkBoxCheck} // <- there is no binding
/>
...
一个示例可以是增量函数:
this.state
如果将这两个setState操作成批分组在一起,则假定值为1:
this.setState
这可以通过使用将先前状态作为第一个参数的回调来避免:
function increment() {
this.setState({value: this.state.value + 1});
}
然后,即使事情成批发生,react也会以正确和更新的状态调用参数。上面的示例如下所示:
setState({value: 1 + 1})
setState({value: 1 + 1})
参考:
答案 1 :(得分:1)
之所以会这样,是因为您需要将this.checkBoxCheck
绑定到this
。
将以下内容添加到您的构造函数中:this.checkBoxCheck = this.checkBoxCheck.bind(this)
。
示例:
//App.js
export class Login extends Component {
constructor(props) {
super(props);
this.state = { remember: false };
this.checkBoxCheck = this.checkBoxCheck.bind(this);
}
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>
);
}
}