我将一个函数移到 class 之外并制作了 const。现在该功能不起作用
I moved a function outside the class and made const. Now the function does not work
我将函数 addONe 移到了 class Counter 之外。执行此操作后,函数 addOne 不再起作用,但另一方面我没有收到任何错误。我的问题是我做错了什么 const addOne 不起作用?
import React from 'react';
const addOne = () => {
this.setState((prevState) => {
return {
count: prevState.count + 1
}
})
}
export default class Counter extends React.Component {
constructor(props) {
super(props);
this.minusOne = this.minusOne.bind(this);
this.reset = this.reset.bind(this);
this.state = {
count: 0
}
}
// addOne() {
// this.setState((prevState) => {
// return {
// count: prevState.count + 1
// }
// })
// }
minusOne() {
this.setState((prevState) => {
return {
count: prevState.count - 1
}
})
}
reset() {
this.setState(() => {
return {
count: 0// count: 0
}
})
}
render() {
return (
<div>
<h1>Count: {this.state.count}</h1>
<button onClick={this.addOne}>+1</button>
<button onClick={this.minusOne}>-1</button>
<button onClick={this.reset}>reset</button>
</div>
)
}
}
它不能工作。
您正在函数内部访问 this.setState
,但您的范围内没有任何 setState
方法,因为它是 React.Component
class 的专有方法.
真正的问题是:为什么要移出 class 和 addOne
功能?
根据您的评论进行编辑
如果你正在学习,你需要一个更技术性的解释:)
首先,您需要在 addOne 函数中访问 React.Component
class 的 setState
方法。我们需要将 this.setState
存在的上下文绑定到此函数。还有什么比组件本身的上下文更好?
让我们更新渲染方法来替换这一行:
<button onClick={this.addOne}>+1</button>
这个:
<button onClick={addOne.bind(this)}>+1</button>
这里发生了什么?函数 addOne
正在接收外部上下文(在本例中为 this
)。此上下文将用作函数内的 this
关键字。从技术上讲,绑定另一个上下文会创建一个新的有界函数,但这是我们在这里不关心的另一件事。
如果您尝试这个小小的修改,它仍然不起作用。
那是因为您将 addOne
声明为 lambda 函数表达式。在 ES6 中,lambda 函数不能绑定其他上下文。
事实上,如果将 addOne 从 lambda 函数表达式转换为函数声明,如下所示:
function addOne() {
this.setState(prevState => ({
count: prevState.count + 1
}));
}
...您会看到增加的效果正常:)
希望它能帮助您了解这里发生的事情。
保持 ES6 语法
现在,使用 ES6 lambda 函数表达式并非不可能,它只是把同样的问题稍微移到一边。我们不能绑定另一个上下文,但我们可以在它上面保持闭包,调用驻留或具有正确上下文的方法。
例如,我们可以将 addOne
函数表达式转换为高阶函数,它采用 setState
和 return 您需要的点击处理程序:
const addOne = setState => () =>
setState(prevState => ({
count: prevState.count + 1
}))
现在,在render方法中,我们可能会想这样使用它:
<button onClick={addOne(this.setState)}>+1</button>
将 setState
作为函数引用传递。
现在的微妙问题是 addOne
函数中的 setState
没有原始上下文绑定!
我们可以这样解决:
<button onClick={addOne(this.setState.bind(this))}>+1</button>
根据您最后的评论进行编辑
这些语法的行为完全相同:
const addOne = setState => () =>
setState(prevState => ({
count: prevState.count + 1
}))
const addOne = setState => () =>
setState(prevState => {
return { count: prevState.count + 1 }
})
它们的工作方式相同,因为对于 lambda 函数表达式,如果您将单个语句作为函数的主体,则该语句的计算结果会自动 returned。
这意味着 lambda 函数可以短至:
const five = () => 5
// five() returns immediate value 5
说,当你有:
prevState => {
return { count: prevState.count + 1 }
}
您正在用一条语句创建主体,return是一个普通对象。
你看到相似之处了吗?你在做同样的事情:有一个声明 returns something.
您可能首先想到的是重写它,省略 return
关键字,例如:
prevState => {
count: prevState.count + 1
}
但这行不通。由于不应该存在的冒号字符,它会给您一个语法错误。它不应该存在,因为如果 lambda 函数表达式主体被定义为一个块(用 {}
包装所有内容),它应该有多个语句,也许还有一个 return
关键字。
为了使其工作,我们需要将普通对象定义视为单个语句,我们通过将其包装在圆括号中来实现,例如:
prevState => ({
count: prevState.count + 1
})
再次希望对您有所帮助:)
我将函数 addONe 移到了 class Counter 之外。执行此操作后,函数 addOne 不再起作用,但另一方面我没有收到任何错误。我的问题是我做错了什么 const addOne 不起作用?
import React from 'react';
const addOne = () => {
this.setState((prevState) => {
return {
count: prevState.count + 1
}
})
}
export default class Counter extends React.Component {
constructor(props) {
super(props);
this.minusOne = this.minusOne.bind(this);
this.reset = this.reset.bind(this);
this.state = {
count: 0
}
}
// addOne() {
// this.setState((prevState) => {
// return {
// count: prevState.count + 1
// }
// })
// }
minusOne() {
this.setState((prevState) => {
return {
count: prevState.count - 1
}
})
}
reset() {
this.setState(() => {
return {
count: 0// count: 0
}
})
}
render() {
return (
<div>
<h1>Count: {this.state.count}</h1>
<button onClick={this.addOne}>+1</button>
<button onClick={this.minusOne}>-1</button>
<button onClick={this.reset}>reset</button>
</div>
)
}
}
它不能工作。
您正在函数内部访问 this.setState
,但您的范围内没有任何 setState
方法,因为它是 React.Component
class 的专有方法.
真正的问题是:为什么要移出 class 和 addOne
功能?
根据您的评论进行编辑
如果你正在学习,你需要一个更技术性的解释:)
首先,您需要在 addOne 函数中访问 React.Component
class 的 setState
方法。我们需要将 this.setState
存在的上下文绑定到此函数。还有什么比组件本身的上下文更好?
让我们更新渲染方法来替换这一行:
<button onClick={this.addOne}>+1</button>
这个:
<button onClick={addOne.bind(this)}>+1</button>
这里发生了什么?函数 addOne
正在接收外部上下文(在本例中为 this
)。此上下文将用作函数内的 this
关键字。从技术上讲,绑定另一个上下文会创建一个新的有界函数,但这是我们在这里不关心的另一件事。
如果您尝试这个小小的修改,它仍然不起作用。
那是因为您将 addOne
声明为 lambda 函数表达式。在 ES6 中,lambda 函数不能绑定其他上下文。
事实上,如果将 addOne 从 lambda 函数表达式转换为函数声明,如下所示:
function addOne() {
this.setState(prevState => ({
count: prevState.count + 1
}));
}
...您会看到增加的效果正常:)
希望它能帮助您了解这里发生的事情。
保持 ES6 语法
现在,使用 ES6 lambda 函数表达式并非不可能,它只是把同样的问题稍微移到一边。我们不能绑定另一个上下文,但我们可以在它上面保持闭包,调用驻留或具有正确上下文的方法。
例如,我们可以将 addOne
函数表达式转换为高阶函数,它采用 setState
和 return 您需要的点击处理程序:
const addOne = setState => () =>
setState(prevState => ({
count: prevState.count + 1
}))
现在,在render方法中,我们可能会想这样使用它:
<button onClick={addOne(this.setState)}>+1</button>
将 setState
作为函数引用传递。
现在的微妙问题是 addOne
函数中的 setState
没有原始上下文绑定!
我们可以这样解决:
<button onClick={addOne(this.setState.bind(this))}>+1</button>
根据您最后的评论进行编辑
这些语法的行为完全相同:
const addOne = setState => () =>
setState(prevState => ({
count: prevState.count + 1
}))
const addOne = setState => () =>
setState(prevState => {
return { count: prevState.count + 1 }
})
它们的工作方式相同,因为对于 lambda 函数表达式,如果您将单个语句作为函数的主体,则该语句的计算结果会自动 returned。
这意味着 lambda 函数可以短至:
const five = () => 5
// five() returns immediate value 5
说,当你有:
prevState => {
return { count: prevState.count + 1 }
}
您正在用一条语句创建主体,return是一个普通对象。
你看到相似之处了吗?你在做同样的事情:有一个声明 returns something.
您可能首先想到的是重写它,省略 return
关键字,例如:
prevState => {
count: prevState.count + 1
}
但这行不通。由于不应该存在的冒号字符,它会给您一个语法错误。它不应该存在,因为如果 lambda 函数表达式主体被定义为一个块(用 {}
包装所有内容),它应该有多个语句,也许还有一个 return
关键字。
为了使其工作,我们需要将普通对象定义视为单个语句,我们通过将其包装在圆括号中来实现,例如:
prevState => ({
count: prevState.count + 1
})
再次希望对您有所帮助:)