我有一个容器,我需要更改显示表单或显示成功页面的UI表单。
容器有一个state.showSuccess,我需要MyFormModule才能调用容器来改变状态。
以下代码有效,但我收到以下警告:
“JSX道具不应该使用.bind()”
如何在不使用.bind()的情况下使其工作?
...
const myPage = class extends React.Component {
state = { showSuccess: false };
showSuccess() {
this.setState({
showSuccess: true,
});
}
render() {
const { showSuccess } = this.state;
if (showSuccess) {...}
....
<MyFormModule showSuccess={this.showSuccess.bind(this)} />
答案 0 :(得分:10)
您应该先understand WHY this is a bad practice。
这里的主要原因是.bind
正在返回一个新的函数引用
这将在每次render
来电时发生,这可能会导致性能下降。
你有两个选择:
使用构造函数bind
您的处理程序(这只会一次)。
constructor(props) {
super(props);
this.showSuccess = this.showSuccess.bind(this);
}
或者使用arrow functions创建处理程序,以便他们使用。{
this
的词汇上下文,因此您不需要bind
它们
全部(you will need a babel plugin):
showSuccess = () => {
this.setState({
showSuccess: true,
});
}
你应该不使用这种模式(正如其他人建议的那样):
showSuccess={() => this.showSuccess()}
因为这也会在每个渲染上创建一个新函数 所以你可以绕过警告,但你仍然在编写一个糟糕的实践设计代码。
来自ESLint docs:
JSX道具中的绑定调用或箭头函数将创建一个全新的 每个渲染都有效。这对性能不利 将导致垃圾收集器被调用的方式多于 必要。如果是全新的,它也可能导致不必要的重新渲染 function作为prop传递给使用reference的组件 对prop进行等式检查以确定它是否应该更新。
答案 1 :(得分:1)
定义showSuccess时使用箭头功能
showSuccess = () => {
this.setState({
showSuccess: true,
});
}
答案 2 :(得分:0)
使用箭头功能,因为它们会自动继承this
上下文的任何位置。
showSuccess={() => this.showSuccess()}
以下是此主题的facebook documentation链接,其中列出了此方法作为解决方案。有趣的是,他们还使用道具中的.bind
作为解决方案之一列出,即使它在实际使用时会产生警告。
从该文档中,您会注意到这是一个潜在的性能问题,因为该函数将在每次渲染时重新创建:
注意:
在渲染中使用箭头功能每次创建一个新函数 组件渲染,可能会影响性能(请参阅 下文)。
但也来自同一个链接:
在渲染方法中使用箭头函数是否可以?一般来说, 是的,没关系,这通常是传递参数的最简单方法 回调函数。
如果您确实遇到性能问题,请务必进行优化!
所以我想说如果你的组件会经常重新渲染,你应该使用其他解决方案之一:在构造函数中绑定,或者首先用箭头函数定义方法。但如果没有,请使用对您来说最干净的方法。