javascript - react js中的绑定函数
问题描述
我以两种方式绑定函数,第一种工作正常,但在 return 方法中使用 es6 函数语法是一种不好的方法,因为它在每个实例上调用一个新方法,所有代码都工作正常,我只需要帮助绑定功能。return 语句中的绑定工作正常。
import React, { Component } from 'react';
import './ColorBox.css';
export default class ColorBox extends Component{
//Constructor
constructor(props){
super(props);
this.state = { copied: false};
}
// Not binded because its called inside the binded function, althrough it doesnot matter
changeCopyState(){
this.setState({ copied: true}, () => (
setTimeout(() => (
this.setState({copied: false})
), 1500)
))
}
// Function to copy color code to clipboard
copyToClipBoard(str) {
const element = document.createElement('textarea');
element.value = str;
document.body.appendChild(element);//insert textarea into html body
element.select();
document.execCommand('copy');//internal command to copy from text area
document.body.removeChild(element);//remove after coping command
this.changeCopyState();
}
render(){
let {name, background} = this.props;
let {copied} = this.state;
return (
<div style={{ background}} className="ColorBox">
<div style={{ background }} className={`copy-overlay ${ copied && "show"}`} />
<div className="box-content">
<span>{name}</span>
</div>
<button className="copy-button" onClick={() => this.copyToClipBoard(background)}>Copy</button>
<span className="more-shades">More</span>
</div>
)
}
}
现在如果我尝试在构造函数中绑定函数,它会给我一个超出调用函数限制等的错误,为什么会发生这种行为。
import React, { Component } from 'react';
import './ColorBox.css';
export default class ColorBox extends Component{
//Constructor
constructor(props){
super(props);
this.state = { copied: false};
this.copyToClipBoard = this.copyToClipBoard.bind(this);
}
// Not binded because its called inside the binded function, althrough it doesnot matter
changeCopyState(){
this.setState({ copied: true}, () => (
setTimeout(() => (
this.setState({copied: false})
), 1500)
))
}
// Function to copy color code to clipboard
copyToClipBoard(str) {
const element = document.createElement('textarea');
element.value = str;
document.body.appendChild(element);//insert textarea into html body
element.select();
document.execCommand('copy');//internal command to copy from text area
document.body.removeChild(element);//remove after coping command
this.changeCopyState();
}
render(){
let {name, background} = this.props;
let {copied} = this.state;
return (
<div style={{ background}} className="ColorBox">
<div style={{ background }} className={`copy-overlay ${ copied && "show"}`} />
<div className="box-content">
<span>{name}</span>
</div>
<button className="copy-button" onClick={this.copyToClipBoard(background)}>Copy</button>
<span className="more-shades">More</span>
</div>
)
}
}
解决方案
问题
onClick={this.copyToClipBoard(background)}
立即调用回调,从而导致您看到的渲染循环。
解决方案
转换
copyToClipBoard
为 curried 函数,以便它使用一个background
参数,在范围内关闭,并返回一个用作回调的函数。// Function to copy color code to clipboard copyToClipBoard(str) { return () => { const element = document.createElement('textarea'); element.value = str; document.body.appendChild(element); //insert textarea into html body element.select(); document.execCommand('copy'); //internal command to copy from text area document.body.removeChild(element); //remove after coping command this.changeCopyState(); }; }
用法:
<button className="copy-button" onClick={this.copyToClipBoard(background)} // <-- returns callback handler > Copy </button>
转换
copyToClipBoard
为 curried 箭头函数,因此this
会自动绑定,您不需要在constructor
.// Function to copy color code to clipboard copyToClipBoard = (str) => () => { const element = document.createElement('textarea'); element.value = str; document.body.appendChild(element); //insert textarea into html body element.select(); document.execCommand('copy'); //internal command to copy from text area document.body.removeChild(element); //remove after coping command this.changeCopyState(); };
用法:
<button className="copy-button" onClick={this.copyToClipBoard(background)} // <-- returns callback handler > Copy </button>
background
已经在 中可用props
,只需从那里使用它。// Function to copy color code to clipboard copyToClipBoard(str) { const { background } = this.props; // <-- destructure from props const element = document.createElement('textarea'); element.value = background; // <-- use background document.body.appendChild(element); //insert textarea into html body element.select(); document.execCommand('copy'); //internal command to copy from text area document.body.removeChild(element); //remove after coping command this.changeCopyState(); }
用法:
<button className="copy-button" onClick={this.copyToClipBoard} // <-- just attach handler > Copy </button>
推荐阅读
- sql-server - 如何将行转换为列
- css - 缺少 Wordpress 子主题 css
- orientdb - ODatabasePool 与 OPartitionedDatabasePool 没有关系
- html - HTML 中的 Unicode 规范化:Firefox 与 Chrome
- javascript - 在谷歌可视化线上绘制 x 轴日期
- windows - 如何在 Windows 上启用 postgresql 自动备份?
- python - 将属性分配给 Scrapy 中的错误项目
- sql - 需要从 3 个表中检索列
- javascript - 操作后如何保持原始日期格式?
- android - 尝试在空对象引用上调用虚拟方法“boolean androidx.work.State.isFinished()”