问题描述
试图弄清React的基础.
Trying to figure out the basics of React.
请看此页面上的第二个示例: https://facebook.github.io/react/一个>我看到tick()函数设置了Timer类的状态,将前一个值增加了一个.
Looking at the second example on this page: https://facebook.github.io/react/I see that the tick() function sets the state of the Timer class, incrementing the previous value by one.
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = {secondsElapsed: 0};
}
tick() {
this.setState((prevState) => ({
secondsElapsed: prevState.secondsElapsed + 1
}));
}
componentDidMount() {
this.interval = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>
);
}
}
ReactDOM.render(<Timer />, mountNode);
但是,当我尝试实现自己的简单Counter类时,它失败了,并且出现了控制台错误,提示无法读取未定义的setState属性.
However, when I tried to implement my own simple Counter class, it failed and I got a console error saying Cannot read property setState of undefined.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: 0};
}
increment(prevState) {
this.setState((prevState) => ({
count: prevState.count + 1
}));
}
render() {
return (
<div className="main">
<button onClick={this.increment}>{this.state.count}</button>
</div>
)
}
}
一些谷歌搜索显示我必须将其绑定到增量函数.但是,为什么在我看到的第一个示例中不需要这样做?我将代码复制到CodePen,并在React 15.3.1上运行良好,在该示例中找不到任何类似于绑定的内容.只有在构造函数中添加绑定代码后,示例中的内容才开始起作用.
Some Googling reveals that I have to bind this to the increment function. But why was that not required in the first example that I saw? I copied the code to CodePen and it ran fine with React 15.3.1 I cannot find anything resembling binding in that example. Only after I added binding code in the constructor did things start working in my example.
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: 0};
// THIS ONE LINE FIXED THE ISSUE
this.increment = this.increment.bind(this);
}
increment(prevState) {
this.setState((prevState) => ({
count: prevState.count + 1
}));
}
render() {
return (
<div className="main">
<button onClick={this.increment}>{this.state.count}</button>
</div>
)
}
}
推荐答案
回答您的问题:第一个示例使用arrow functions
,它会自动执行上下文绑定.从文档中:
Answering your question: the first example uses arrow functions
, that automatically performs context binding. From the docs:
实际上,React中有一些绑定方法:
Indeed there are some ways of binding in React:
1)您可以绑定构造函数中的所有函数,如您所说:
1) you can bind all functions in your constructor, like you said:
constructor(props) {
/* ... */
this.increment = this.increment.bind(this);
}
2)使用箭头函数调用回调:
2) invoke your callbacks with arrow functions:
<button onClick={(e) => this.increment(e)}>
3)附加 .bind
每次将其设置为回调时,在方法引用末尾的a>,如下所示:
3) append .bind
at the end of your method reference each time you set it as a callback, like this:
<button onClick={this.increment.bind(this)}>
4)在您的类中,使用箭头函数定义方法:
4) In your class, define the method with arrow functions:
increment = (e) => {
/* your class function defined as ES6 arrow function */
}
/* ... */
<button onClick={this.increment}>
为了与babel一起使用此语法,您必须启用此插件或使用 stage-2 预设.
In order to use this syntax with babel, you have to enable this plugin or use stage-2 preset.
这篇关于React-为什么在此示例中不需要绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!