React元件中的事件處理函式
阿新 • • 發佈:2020-12-14
constructor函式中bind
class ReactEvent extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Click');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
使用箭頭函式(實驗語法,尚未標準化)
render中使用箭頭函式
class ReactEvent extends Component {
handleClick() {
console.log('Click');
}
render() {
return <button onClick={() => this.handleClick()}>Click Me</button>;
}
}
使用class fields語法(https://babeljs.io/docs/en/ba...)
class ReactEvent extends Component {
//此函式會被繫結到ReactEvent類的例項
handleClick = () => {
console.log('Click');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
在render中使用bind
class ReactEvent extends Component {
handleClick() {
console.log('Click');
}
render() {
return <button onClick={this.handleClick.bind(this)}>Click Me</button>;
}
}
幾種方式比較
影響 | constructor函式中bind | 使用class fields語法 | render中使用箭頭函式 | 在render中使用bind |
---|---|---|---|---|
render時生成新函式 | 否 | 否 | 是 | 是 |
效能 | 無影響 | 無影響 | 有影響 | 有影響 |
可直接攜帶引數 | 否 | 否 | 是 | 是 |
簡潔性 | 不好 | 好 | 好 | 好 |
上表中我們看到,在render中直接bind或者箭頭函式都會影響效能,原因在於,在render 中的bind和箭頭函式在每次render時都會建立新的函式,導致子元件的props發生改變,這在PureComponent中會影響效能,除非自己在shouldComponentUpdate中進行優化。
//僅作為示例程式碼,不遵循常用程式碼規範
//子元件
class Button extends React.PureComponent {
render() {
console.log('================')
return (
<button onClick={this.props.handleClick}>hahaha</button>
)
}
}
//父元件
class ButtonList extends React.Component {
constructor(props) {
super(props);
this.state = {
index: -1,
list: [1, 2, 3, 4]
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log('Click');
}
onStateChange = () => {
this.setState({
index: 1
});
}
render() {
return (
<div>
<button onClick={this.onStateChange}>stateChange</button>
{
this.state.list.map(item => <Button handleClick={this.handleClick}/>)
}
</div>
)
}
}
ReactDOM.render(
<ButtonList />, document.getElementById('root')
);
1
事件處理中傳參
在開發當中,經常遇到對一個列表做操作,可能包含刪除,修改,檢視。這時候繫結事件就需要傳參,通常為id。
直接傳遞引數
//render中使用箭頭函式
{
this.state.list.map(item => (
<Button onClick={() => this.handleClick(item.id)}/>
))
}
//render中使用bind
{
this.state.list.map(item => (
<Button onClick={this.handleClick.bind(this, item.id)}/>
))
}
使用data屬性
//handleClick中通過e.target.dataset.id獲取
{
this.state.list.map(item => (
<Button data-id={item.id} onClick={this.handleClick}/>
))
}
資源搜尋網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com
總結
這裡不強制推薦使用哪一種,對於各個團隊來說,可以根據專案,選擇自己團隊的事件繫結方式。
因為箭頭函式的簡潔性,在公司專案中,我們團隊通常使用class fields 定義箭頭函式來繫結事件。當需要傳參的時,單個引數傳遞使用data屬性傳參。多個引數傳遞時,採用拆分子元件的方式回撥傳參。
//子元件
class Button extends React.PureComponent {
handleClick = () => {
this.props.handleClick(this.props.item);
}
render() {
return (
<button onClick={this.handleClick}>hahaha</button>
)
}
}
//父元件
class ButtonList extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [1, 2, 3, 4]
};
}
handleClick = (item) => {
console.log('Click', item);
}
render() {
const { list=[] } = this.state;
return (
<div>
{
list.map(item => <Button handleClick={this.handleClick} item={item}/>)
}
</div>
)
}
}
ReactDOM.render(
<ButtonList />, document.getElementById('root')
);